it-swarm.com.de

Wie kann ich feststellen, ob auf eine Datenbanktabelle mehr zugegriffen wird? Willst du so etwas wie ein "SELECT-Trigger"

Ich habe eine sehr große Datenbank mit Hunderten von Tabellen und nach vielen, vielen Produkt-Upgrades bin ich sicher, dass die Hälfte von ihnen nicht mehr verwendet wird. Wie kann ich feststellen, ob eine Tabelle aktiv ausgewählt wird? Ich kann nicht nur Profiler verwenden - ich möchte nicht nur länger als ein paar Tage beobachten, sondern es gibt auch Tausende von gespeicherten Prozeduren, und der Profiler übersetzt die SP) - Aufrufe nicht in Tabellenzugriffsaufrufe.

Ich kann mir nur vorstellen, einen Clustered-Index für die gewünschten Tabellen zu erstellen und dann den sys.dm_db_index_usage_stats Zu überwachen, um festzustellen, ob der Clustered-Index Suchvorgänge oder Überprüfungen enthält, was bedeutet, dass Daten aus der Tabelle vorhanden sind geladen. Das Hinzufügen eines Clustered-Index für jede Tabelle ist jedoch (aus einer Reihe von Gründen) eine schlechte Idee, da dies nicht wirklich durchführbar ist.

Gibt es andere Möglichkeiten, die ich habe? Ich wollte schon immer eine Funktion wie einen "SELECT-Trigger", aber es gibt wahrscheinlich auch andere Gründe, warum SQL Server diese Funktion nicht hat.

LÖSUNG:

Danke, Remus, dass du mich in die richtige Richtung gelenkt hast. Unter Verwendung dieser Spalten habe ich das folgende SELECT erstellt, das genau das tut, was ich will.

  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)
56
SqlRyan

Schauen Sie in sys.dm_db_index_usage_stats . Die Spalten last_user_xxx enthalten den Zeitpunkt, zu dem Benutzeranforderungen zum letzten Mal auf die Tabelle zugegriffen haben. Diese Tabelle setzt ihre Nachverfolgung nach einem Serverneustart zurück. Sie müssen sie daher eine Weile laufen lassen, bevor Sie sich auf ihre Daten verlassen können.

40
Remus Rusanu

Betreff: Wenn Sie den Profiler auf SP: StmtCompleted überwachen, werden alle Anweisungen erfasst, die in einer gespeicherten Prozedur ausgeführt werden, sodass Tabellenzugriffe innerhalb eines Sprocs abgefangen werden. Wenn nicht alles gespeicherte Prozeduren durchläuft, benötigen Sie möglicherweise auch das SQL: StmtCompleted -Ereignis.

Es wird eine große Anzahl von Ereignissen geben, daher ist es wahrscheinlich immer noch nicht praktikabel, eine lange Zeitspanne zu verfolgen, da es sich um eine Ablaufverfolgungsgröße handelt. Sie können jedoch einen Filter anwenden - z. Dabei enthält TextData den Namen Ihrer Tabelle, nach der Sie suchen möchten. Sie können eine Liste von Tabellennamen angeben, nach denen Sie jederzeit filtern und schrittweise durcharbeiten können. Sie sollten also keine Trace-Ereignisse erhalten, wenn auf keine dieser Tabellen zugegriffen wurde.

Auch wenn Sie der Meinung sind, dass dies kein geeigneter Ansatz für Sie ist, dachte ich, dass es sich lohnt, darauf einzugehen.

Eine andere Lösung wäre eine globale Suche in Ihrem Quellcode, um Verweise auf die Tabellen zu finden. Sie können die Definitionen der gespeicherten Prozeduren abfragen, um nach Übereinstimmungen für eine bestimmte Tabelle zu suchen, oder einfach ein vollständiges Datenbankskript generieren und danach nach Tabellennamen suchen.

6
AdaTheDev

Für SQL Server 2008 sollten Sie sich SQL Auditing ansehen. Auf diese Weise können Sie viele Dinge überwachen, einschließlich Auswahlen in einer Tabelle und Berichte in einer Datei oder einem Ereignisprotokoll.

3
dr.

Die folgende Abfrage verwendet den Abfrageplan-Cache, um festzustellen, ob in einem der vorhandenen Pläne im Cache ein Verweis auf eine Tabelle vorhanden ist. Es wird nicht garantiert, dass dies zu 100% korrekt ist (da Abfragepläne gelöscht werden, wenn Speicherbeschränkungen vorliegen), dies kann jedoch verwendet werden, um Einblicke in die Verwendung von Tabellen zu erhalten.

SELECT schema_name(schema_id) as schemaName, t.name as tableName,
    databases.name,
dm_exec_sql_text.text AS TSQL_Text,
dm_exec_query_stats.creation_time, 
dm_exec_query_stats.execution_count,
dm_exec_query_stats.total_worker_time AS total_cpu_time,
dm_exec_query_stats.total_elapsed_time, 
dm_exec_query_stats.total_logical_reads, 
dm_exec_query_stats.total_physical_reads, 
dm_exec_query_plan.query_plan
FROM sys.dm_exec_query_stats 
CROSS APPLY sys.dm_exec_sql_text(dm_exec_query_stats.plan_handle)
CROSS APPLY sys.dm_exec_query_plan(dm_exec_query_stats.plan_handle)
INNER JOIN sys.databases ON dm_exec_sql_text.dbid = databases.database_id
RIGHT JOIN sys.tables t (NOLOCK) ON cast(dm_exec_query_plan.query_plan as varchar(max)) like '%' + t.name + '%'

Ein kleiner Hinweis: Wenn Sie beabsichtigen, diese Tabellen zu löschen, müssen Sie möglicherweise gesetzliche Verpflichtungen in Betracht ziehen, die es Ihnen auferlegen, die betroffenen Daten trotzdem x Jahre lang aufzubewahren.

0
Erwin Smout

Ich hatte vor, mit Benutzerberechtigungen für verschiedene Tische zu spielen, aber dann fiel mir ein, dass Sie Trace mit einem ON LOGON-Trigger aktivieren können, von dem Sie möglicherweise profitieren:

CREATE OR REPLACE TRIGGER SYS.ON_LOGON_ALL

AFTER LOGON ON DATABASE
WHEN (

USER 'MAX'

)
BEGIN

EXECUTE IMMEDIATE 'ALTER SESSION SET SQL_TRACE TRUE';

--EXECUTE IMMEDIATE 'alter session set events ''10046 trace name context forever level 12''';

EXCEPTION

WHEN OTHERS THEN

NULL;

END;

/

Dann können Sie Ihre Trace-Dateien überprüfen.

0
Pentium10