Поделиться через


Устранение распространенных проблем с производительностью с помощью хэш-индексов Memory-Optimized

В этом разделе рассматриваются устранение неполадок и устранение распространенных проблем с хэш-индексами.

Для поиска требуется подмножество ключевых столбцов хэш-индекса

Выпуск: Хэш-индексы требуют значений для всех ключевых столбцов индекса для вычисления хэш-значения и поиска соответствующих строк в хэш-таблице. Таким образом, если запрос включает предикаты равенства только для подмножества ключей индекса в предложении WHERE, SQL Server не может использовать индекс для поиска строк, соответствующих предикатам в предложении WHERE.

В отличие от этого, упорядоченные индексы, такие как некластеризованные индексы на основе диска и оптимизированные для памяти индексы, поддерживают поиск подмножества ключевых столбцов индекса, если они являются ведущими столбцами в индексе.

Симптом: Это приводит к снижению производительности, так как SQL Server должен выполнять полные проверки таблиц, а не поиск индекса, что обычно является более быстрой операцией.

Как устранить неполадки: Помимо снижения производительности, проверка планов запросов будет показывать сканирование вместо обращения к индексу. Если запрос довольно простой, проверка текста запроса и определения индекса также покажет, требуется ли поиск подмножества ключевых столбцов индекса.

Рассмотрим следующую таблицу и запрос:

CREATE TABLE [dbo].[od]  
(  
     o_id INT NOT NULL,  
     od_id INT NOT NULL,  
     p_id INT NOT NULL,  
     CONSTRAINT PK_od PRIMARY KEY NONCLUSTERED HASH (o_id, od_id) WITH (BUCKET_COUNT = 10000)  
)  
WITH (MEMORY_OPTIMIZED = ON)  
  
 SELECT p_id  
 FROM dbo.od  
 WHERE o_id=1  

В таблице есть хэш-индекс для двух столбцов (o_id, od_id), а запрос имеет предикат равенства (o_id). Так как запрос имеет предикаты равенства только в подмножестве ключевых столбцов индекса, SQL Server не может выполнять операцию поиска индекса с помощью PK_od; Вместо этого SQL Server должен вернуться к полной проверке индекса.

Обходные пути: Существует ряд возможных обходных решений. Рассмотрим пример.

  • Повторно создайте индекс как тип, некластеризованный вместо некластеризованного хэша. Индекс, оптимизированный для памяти и не кластеризированный, упорядочивается, поэтому SQL Server может выполнять поиск по ведущим ключевым столбцам индекса. Результирующее определение первичного ключа для примера будет constraint PK_od primary key nonclustered.

  • Измените текущий ключ индекса, чтобы соответствовать столбцам в предложении WHERE.

  • Добавьте новый хэш-индекс, соответствующий столбцам в предложении WHERE запроса. В примере результирующее определение таблицы будет рассматриваться следующим образом:

    CREATE TABLE dbo.od  
     ( o_id INT NOT NULL,  
     od_id INT NOT NULL,  
     p_id INT NOT NULL,  
    
     CONSTRAINT PK_od PRIMARY KEY   
     NONCLUSTERED HASH (o_id,od_id) WITH (BUCKET_COUNT=10000),  
    
     INDEX ix_o_id NONCLUSTERED HASH (o_id) WITH (BUCKET_COUNT=10000)  
    
     ) WITH (MEMORY_OPTIMIZED=ON)  
    

Обратите внимание, что хэш-индекс, оптимизированный для памяти, не выполняется оптимально, если для заданного значения ключа индекса имеется много повторяющихся строк: в примере, если число уникальных значений для столбца o_id гораздо меньше числа строк в таблице, не будет оптимальным для добавления индекса (o_id); Вместо этого изменение типа индекса PK_od с хэша на некластеризованный будет лучшим решением. Дополнительные сведения см. в разделе "Определение правильного количества сегментов для хэш-индексов".

См. также

Индексы в таблицах Memory-Optimized