Freigeben über


sys.dm_db_xtp_hash_index_stats (Transact-SQL)

Gilt für: SQL Server Azure SQL-Datenbank Azure SQL Managed Instance

Diese Statistiken sind nützlich, um die Bucketanzahl für Hashindizes in speicheroptimierten Tabellen zu verstehen und zu optimieren. Sie kann auch verwendet werden, um Fälle zu erkennen, in denen der Indexschlüssel viele Duplikate aufweist.

Eine große durchschnittliche Kettenlänge weist darauf hin, dass viele Zeilen demselben Hashbucket hinzugefügt werden. Dies könnte folgende Ursachen haben:

  • Wenn die Anzahl der leeren Buckets niedrig ist oder die durchschnittliche und die maximale Kettenlänge ähnlich sind, besteht die Wahrscheinlichkeit, dass die Bucketgesamtanzahl zu niedrig ist. Dies führt dazu, dass viele verschiedene Indexschlüssel demselben Hashbucket hinzugefügt werden.

  • Wenn die Anzahl leerer Buckets hoch ist oder die maximale Kettenlänge relativ zur durchschnittlichen Kettenlänge hoch ist, gibt es zwei wahrscheinliche Erklärungen. Es gibt viele Zeilen mit doppelten Indexschlüsselwerten, oder es gibt eine Schiefe in den Schlüsselwerten. In beiden Fällen führen alle Zeilen mit demselben Indexschlüsselwerthash auf denselben Bucket, was zu einer langen Kettenlänge in diesem Bucket führt.

Lange Kettenlängen können sich erheblich auf die Leistung aller DML-Vorgänge in einzelnen Zeilen auswirken, einschließlich SELECT und INSERT. Kurze Kettenlängen in Kombination mit einer hohen Anzahl von leeren Buckets weisen auf eine zu hohe Bucketanzahl hin. Dadurch wird die Leistung von Indexscans verringert.

Warnung

Dieser DMV überprüft die gesamte Tabelle. Wenn es also große Tabellen in Ihrer Datenbank gibt, sys.dm_db_xtp_hash_index_stats kann es lange dauern.

Weitere Informationen finden Sie unter Hashindizes für speicheroptimierte Tabellen.

Spaltenname type Beschreibung
object_id int Die Objekt-ID der übergeordneten Tabelle.
xtp_object_id bigint ID der speicheroptimierten Tabelle.
index_id int Die Index-ID.
total_bucket_count bigint Die Gesamtanzahl der Hashbuckets im Index.
empty_bucket_count bigint Die Anzahl der leeren Hashbuckets im Index.
avg_chain_length bigint Die durchschnittliche Länge der Zeilenketten für alle Hashbuckets im Index.
max_chain_length bigint Die maximale Länge der Zeilenketten in den Hashbuckets.
xtp_object_id bigint Die IN-Memory OLTP-Objekt-ID, die der speicheroptimierten Tabelle entspricht.

Berechtigungen

Erfordert die VIEW DATABASE STATE-Berechtigung für die Datenbank.

Berechtigungen für SQL Server 2022 und höher

Erfordert die VIEW DATABASE PERFORMANCE STATE-Berechtigung für die Datenbank.

Beispiele

A. Problembehandlung bei Hashindex-Bucketanzahl

Die folgende Abfrage kann verwendet werden, um die Hashindex-Bucketanzahl einer vorhandenen Tabelle zu beheben. Die Abfrage gibt Statistiken über den Prozentsatz der leeren Buckets und die Kettenlänge für alle Hashindizes in Benutzertabellen zurück.

  SELECT  
    QUOTENAME(SCHEMA_NAME(t.schema_id)) + N'.' + QUOTENAME(OBJECT_NAME(h.object_id)) as [table],   
    i.name                   as [index],   
    h.total_bucket_count,  
    h.empty_bucket_count,  
    FLOOR((  
      CAST(h.empty_bucket_count as float) /  
        h.total_bucket_count) * 100)  
                             as [empty_bucket_percent],  
    h.avg_chain_length,   
    h.max_chain_length  
  FROM sys.dm_db_xtp_hash_index_stats as h   
  INNER JOIN sys.indexes as i  
            ON h.object_id = i.object_id  
           AND h.index_id  = i.index_id  
    INNER JOIN sys.memory_optimized_tables_internal_attributes ia ON h.xtp_object_id=ia.xtp_object_id
    INNER JOIN sys.tables t on h.object_id=t.object_id
  WHERE ia.type=1
  ORDER BY [table], [index];  

Ausführliche Informationen zum Interpretieren der Ergebnisse dieser Abfrage finden Sie unter "Problembehandlung von Hashindizes für speicheroptimierte Tabellen".

B. Hashindexstatistiken für interne Tabellen

Bestimmte Features verwenden interne Tabellen, die Hashindizes verwenden, z. B. Spaltenspeicherindizes für speicheroptimierte Tabellen. Die folgende Abfrage gibt Statistiken für Hashindizes für interne Tabellen zurück, die mit Benutzertabellen verknüpft sind.

  SELECT  
    QUOTENAME(SCHEMA_NAME(t.schema_id)) + N'.' + QUOTENAME(OBJECT_NAME(h.object_id)) as [user_table],
    ia.type_desc as [internal_table_type],
    i.name                   as [index],   
    h.total_bucket_count,  
    h.empty_bucket_count,  
    h.avg_chain_length,   
    h.max_chain_length  
  FROM sys.dm_db_xtp_hash_index_stats as h   
  INNER JOIN sys.indexes as i  
            ON h.object_id = i.object_id  
           AND h.index_id  = i.index_id  
    INNER JOIN sys.memory_optimized_tables_internal_attributes ia ON h.xtp_object_id=ia.xtp_object_id
    INNER JOIN sys.tables t on h.object_id=t.object_id
  WHERE ia.type!=1
  ORDER BY [user_table], [internal_table_type], [index]; 

Die Bucketanzahl des Indexes für interne Tabellen kann nicht geändert werden, daher sollte die Ausgabe dieser Abfrage nur als informativ betrachtet werden. Es ist keine Aktion erforderlich.

Diese Abfrage wird nicht erwartet, dass Zeilen zurückgegeben werden, es sei denn, Sie verwenden ein Feature, das Hashindizes für interne Tabellen verwendet. Die folgende speicheroptimierte Tabelle enthält einen Spaltenspeicherindex. Nach dem Erstellen dieser Tabelle werden Hashindizes für interne Tabellen angezeigt.

  CREATE TABLE dbo.table_columnstore
  (
      c1 INT NOT NULL PRIMARY KEY NONCLUSTERED,
      INDEX ix_columnstore CLUSTERED COLUMNSTORE
  ) WITH (MEMORY_OPTIMIZED=ON);