Comment puis-je savoir si une table de base de données est plus accessible? Voulez quelque chose comme un “déclencheur”
J'ai une très grande base de données avec des centaines de tables, et après beaucoup, beaucoup de mises à niveau de produits, je suis sûr que la moitié d'entre eux ne sont pas plus utilisées. Comment puis-je savoir si un tableau est activement sélectionnées à partir de? Je ne peut pas utiliser de générateur de profils - non seulement je veux regarder pour plus de quelques jours, mais il y a des milliers de procédures stockées en tant que bien, et le générateur de profils de ne pas traduire le PS appelle dans l'accès à la table des appels.
La seule chose que je peux penser à est de créer un index cluster sur les tables de l'intérêt, et puis surveiller l' sys.dm_db_index_usage_stats
pour voir s'il y a des recherches ou des analyses sur l'index cluster, ce qui signifie que les données de la table a été chargé. Cependant, l'ajout d'un index cluster sur chaque tableau est une mauvaise idée (pour diverses raisons), que n'est pas vraiment possible.
Existe-il d'autres options? J'ai toujours voulu une fonction comme un "déclencheur", mais il y a probablement d'autres raisons pour que SQL Server n'a pas cette fonctionnalité soit.
SOLUTION:
Merci, Remus, pour me pointer dans la bonne direction. L'utilisation de ces colonnes, j'ai créé la sélection suivante, qui fait exactement ce que je veux.
WITH LastActivity (ObjectID, LastAction) AS
(
SELECT object_id AS TableName,
last_user_seek as LastAction
FROM sys.dm_db_index_usage_stats u
WHERE database_id = db_id(db_name())
UNION
SELECT object_id AS TableName,
last_user_scan as LastAction
FROM sys.dm_db_index_usage_stats u
WHERE database_id = db_id(db_name())
UNION
SELECT object_id AS TableName,
last_user_lookup as LastAction
FROM sys.dm_db_index_usage_stats u
WHERE database_id = db_id(db_name())
)
SELECT OBJECT_NAME(so.object_id) AS TableName,
MAX(la.LastAction) as LastSelect
FROM sys.objects so
LEFT
JOIN LastActivity la
on so.object_id = la.ObjectID
WHERE so.type = 'U'
AND so.object_id > 100
GROUP BY OBJECT_NAME(so.object_id)
ORDER BY OBJECT_NAME(so.object_id)
- Est-il un moyen pour capturer ces données dans un tableau lorsque le serveur s'arrête? Cela permettrait à long terme de suivi.
- Grande question. Pour n'importe qui d'autre en regardant cela, si vous utilisez 2008, vous pouvez remplacer les requêtes à l'intérieur de la CTE avec la suivante;
SELECT object_id AS TableName, (SELECT Max(v) FROM (VALUES (last_user_seek), (last_user_scan), (last_user_lookup)) AS value(v)) as [LastAction] FROM sys.dm_db_index_usage_stats u WHERE database_id = db_id(db_name())
Exemple à partir de ici
Vous devez vous connecter pour publier un commentaire.
Regarder dans sys.dm_db_index_usage_stats. Les colonnes last_user_xxx contiendra la dernière fois que la table a été utilisé à partir des demandes des utilisateurs. Ce tableau réinitialise son suivi après un redémarrage du serveur, vous devez le laisser tourner pendant un certain temps avant de compter sur ses données.
Re: Profiler, si vous surveillez pour PS:StmtCompleted, qui permettra de saisir toutes les instructions qui s'exécutent à l'intérieur d'une procédure stockée, donc, ça va attraper table accède à l'intérieur d'une procédure stockée. Si tout ne se passe via des procédures stockées, vous pouvez également avoir besoin de la SQL:StmtCompleted événement.
Il y aura un grand nombre d'événements donc ce n'est probablement pas encore pratique pour tracer sur une longue période en raison de la taille de la trace. Cependant, vous pouvez appliquer un filtre par exemple, où TextData contient le nom de votre table que vous souhaitez vérifier. Vous pouvez donner une liste de noms de table pour filtre à tout moment et de travailler à travers eux petit à petit. Donc, vous ne devriez pas obtenir aucune trace des événements si aucun de ces tables ont été consultées.
Même si vous sentez que c'est pas un bon/approche viable pour vous, j'ai pensé qu'il valait la peine de l'expansion sur.
Une autre solution serait de faire une recherche globale de votre code source pour trouver des références aux tables. Vous pouvez faire une requête de la procédure stockée définitions pour les matchs, pour un tableau, ou tout simplement de générer une base de données complète de script et faites une recherche sur que pour les noms de table.
Pour SQL Server 2008, vous devriez jeter un oeil à SQL Audit. Cela permet de faire une vérification beaucoup de choses y compris sélectionne sur une table et les rapports d'un fichier ou d'un Journal des Événements.
La requête suivante utilise le plan de requête cache pour voir si il y a une référence à une table dans l'un des plans existants dans le cache. Ce n'est pas la garantie d'être précis à 100% (depuis les plans de requête sont vidées, s'il y a des contraintes de mémoire), mais peut être utilisé pour obtenir quelques idées sur la table.
Noter : si votre intention est de laisser tomber ces tables, vous pouvez avoir à tenir compte des obligations juridiques qui l'imposer sur vous pour garder les données de toute façon pour x années.
J'avais dans l'idée de jouer avec les autorisations de l'utilisateur pour les différents tableaux, mais je me souvins alors vous pouvez activer la trace avec un déclencheur d'ouverture de session que vous pourriez bénéficier de ce:
Ensuite, vous pouvez vérifier vos fichiers de trace.
Cette solution fonctionne mieux pour moi, alors la solution ci-dessus. Mais, est encore limted que le serveur n'a pas été re-commencé en tant que bien, mais encore vous donne une bonne idée de les tables ne sont pas utilisés.