Есть ли способ заставить SQL Server автоматически делать выборки по хеш-значениям полей nvarchar? - PullRequest
2 голосов
/ 21 октября 2010

Я не уверен, как лучше сформулировать этот вопрос, так что, возможно, я пропустил ранее заданный вопрос. Не стесняйтесь закрыть это и указать мне правильный, если он существует.

У меня есть таблица с двумя важными столбцами (то есть, у нее гораздо больше, но только два имеют отношение к этому вопросу). Первый столбец - это GUID (идентификатор), а второй - это nvarchar (хранящий URL). Комбинация идентификатора и URL-адреса должна быть уникальной (поэтому один и тот же гид может повторяться, но каждая строка имеет свой URL-адрес и наоборот, но не может быть более одной строки одного и того же guid и URL)

В настоящее время перед каждой INSERT я делаю SELECT, чтобы увидеть, существует ли строка с таким же идентификатором и URL. Однако, похоже, что поиск на nvarchar идет медленно. Поэтому я думаю, что обновлю таблицу для хранения дополнительного столбца, который заполняется хешем (SHA1) URL-адреса при вставке. Теперь мы только ищем меньший хеш (varbinary?), Который, я полагаю, будет значительно быстрее, чем раньше.

Есть ли способ заставить SQL Server 2008 автоматически сохранять хэш и выполнять поиск по этому хэш-значению вместо реального текста? Я предполагаю, что индексы - это b-деревья, поэтому SQL Server должен создать b-дерево с хэш-значениями текста в поле nvarchar, и когда выполняется выбор, он должен вычислить хеш и сделайте поиск в дереве со значением хеша. Это возможно?

Ответы [ 3 ]

3 голосов
/ 21 октября 2010

Если вы выполняете поиск по полям (id, url) - у вас есть индекс для этих двух столбцов? Если нет - добавьте и посмотрите, достаточно ли это ускорит ваш поиск.

Если нет: да, вы определенно можете получить эту функцию автоматически - волшебное слово: вычисляемый столбец .

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

Чтобы сделать это быстро для ваших проверок, вам нужно убедиться, что вы можете сохранить этот вычисляемый столбец - тогда вы тоже можете его проиндексировать. Это исключает более масштабные вычисления - формула должна быть четкой, краткой и детерминированной.

Итак, сделайте это:

ALTER TABLE dbo.YourTable
  ADD HashValue AS CAST(HASHBYTES('SHA1', CAST(ID AS VARCHAR(36)) + Url) AS VARBINARY(20)) PERSISTED

Теперь у вашей таблицы есть новый столбец HashValue (называйте его как хотите), и вы можете выбрать это значение и проверить его.

Затем поместите индекс в этот новый столбец

CREATE NONCLUSTERED INDEX IX_Hash_YourTable
  ON dbo.YourTable(HashValue)

Теперь ваш поиск должен летать!

0 голосов
/ 21 октября 2010

У вас может быть триггер, который вычисляет хэш при вставке и обновлении и вставляет его при необходимости.

Что касается остановки вставки, просто добавьте уникальный индекс для них

0 голосов
/ 21 октября 2010

Не могли бы вы просто наложить уникальное ограничение на таблицу для этих двух столбцов и выполнить вставку внутри блока try / catch?

Это избавит вас от лишней работы по вычислению хеша и лишнего пространства для его хранения

...