Как заставить MS SQL Server прозрачно использовать индекс CHECKSUM / хеш?

Похоже, что SQL Server автоматически не использует индекс CHECKSUM / hash, если столбец CHECKSUM явно не включен в аргументы поиска для запроса. Это проблема, потому что я не контролирую приложения, которые запрашивают таблицу, и я не могу нарушить их производительность.

Есть ли способ заставить SQL Server использовать новый индекс CHECKSUM / hash без изменения запросов, чтобы включить новый столбец CHECKSUM / hash?

Скрипт Repro

CREATE TABLE big_table ( id BIGINT IDENTITY CONSTRAINT pk_big_table PRIMARY KEY, wide_col VARCHAR(50), wide_col_checksum AS CHECKSUM(wide_col), other_col INT ) CREATE INDEX ix_checksum ON big_table (wide_col_checksum) 

Вставьте несколько тестовых данных:

 SET NOCOUNT ON DECLARE @count INT = 0 BEGIN TRANSACTION WHILE @count < 10000 BEGIN SET @count = @count + 1 INSERT INTO big_table (wide_col, other_col) VALUES (SUBSTRING(master.dbo.fn_varbintohexstr(CRYPT_GEN_RANDOM(25)), 3, 50), @count) IF @count % 1000 = 0 BEGIN COMMIT TRANSACTION BEGIN TRANSACTION END END COMMIT TRANSACTION INSERT INTO big_table (wide_col, other_col) VALUES ('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 9999999) 

Устаревший запрос. Вызывает сканирование индексов (BAD):

 SELECT * FROM big_table WHERE wide_col = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 

Кластерное сканирование индексов (BAD)


Обновленный запрос. Причины поиска некластеризованного индекса (хорошо):

 SELECT * FROM big_table WHERE wide_col = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' AND wide_col_checksum = CHECKSUM('ABCDEFGHIJKLMNOPQRSTUVWXYZ') 

Поиск некластеризованного индекса (хороший)

Задний план

Моя таблица очень большая (много сотен миллионов строк), имеет несколько индексов (~ 20), все из которых требуются. Некоторые индексированные столбцы немного шире (~ 50 байт) и имеют несколько повторяющихся значений. Столбцы просматриваются только по принципу равенства. Стол вставляется постоянно.

Вот таблица, сравнивающая «нормальные» индексы и индексы CHECKSUM / hash в приведенной выше таблице примеров, как сжатых, так и не сжимаемых. Данные недавно восстановленных индексов на таблицах с 1 миллионом строк:

Хэш-индексы и сжатие

Сжатие страницы само по себе довольно неэффективно в данных выборки (реальные данные должны сжиматься немного лучше). Индекс хэша достигает уменьшения размера индекса 4X. Сжатие страницы по индексу хеширования позволяет уменьшить размер индекса 6X.

Мои цели с использованием хэш-индексов:

  1. Уменьшите размер этих индексов в памяти, тем самым позволяя SQL Server кэшировать большую долю в ОЗУ, тем самым избегая физических чтений.
  2. Уменьшите размер хранилища.
  3. Уменьшите ввод-вывод индекса для операций INSERT.

Если ваше приложение запрашивает:

 SELECT * FROM big_table WHERE wide_col = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 

Вам нужен указатель на wide_col , а не на wide_col_checksum .

SQL Server хранит индексы как B-дерево. Как предполагает @MartinSmith, уменьшение размера столбцов в индексе действительно уменьшает объем памяти и диска.

SQL Server автоматически не использует индекс контрольной суммы / хэша. Запрос должен использовать хеш-столбец для SQL-сервера, чтобы рассмотреть возможность использования индекса. Поэтому я не вижу, как вы можете достичь своей цели, которая вносит изменения в запросы. Это интересный вопрос, однако, это может быть хороший запрос функции SQL Server.

  • Вычислить хэш MD5 строки UTF8
  • хэш-пароль в SQL Server (asp.net)
  • Сравнение значений PWDEncrypt SQL Server
  • Data Vault 2.0 в SQL Server
  • Давайте будем гением компьютера.