2009-03-18 2 views
9

Если мне нужно получить большую строку из БД, быстрее ли ее искать с помощью самой строки или я получу ее путем хэширования строки и сохранения хеша в БД, а затем поиска на основе этого?Быстрее ли искать большую строку в БД по ее хэш-коду?

Если да, то алгоритм хеширования я должен использовать (безопасность не является проблемой, я ищу для выполнения)

Если это имеет значение: Я использую C# и MSSQL2005

+0

Интересный вопрос! –

+0

не уверен, что это относится к .net или C#, хотя ... –

ответ

4

Я был бы удивлен, если бы это принесло огромные улучшения, и я бы рекомендовал не использовать собственные оптимизационные возможности для поиска БД.

Если вы используете индекс базы данных, то для производительности можно настроить производительность, используя проверенные и надежные методы. Жесткое кодирование собственной оптимизации индекса предотвратит это и может остановить вас для повышения производительности индексирования в будущих версиях БД.

1

Если вы используете поле фиксированной длины и индекс, вероятно, будет быстрее ...

5

В общем случае, вероятно, нет, предполагая, что колонка индексирована. Серверы баз данных предназначены для быстрого и эффективного поиска таких запросов. Некоторые базы данных (например, Oracle) предоставляют варианты построения индексов на основе хэширования.

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

1

Если ваши строки коротки (менее 100 символов в целом), строки будут быстрее.

Если строки большие, HASH поиск может и, скорее всего, будет быстрее.

HashBytes(MD4), кажется, самый быстрый на DML.

3

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

Я бы пошел с быстрым алгоритмом, таким как MD5, поскольку вы не хотите тратить больше времени на хэширование строки, чем потребовалось бы просто искать его.

Последнее, что я могу сказать, это то, что вы узнаете, лучше ли это, если вы попробуете его, а - меру.

1

Вы выполняете матч или защитный код? Для совпадения вы должны позволить дескриптору db (но добавить некластеризованный индекс) и просто протестировать через WHERE table.Foo = @foo. Для состязания вы, возможно, смотрите на full text index.

1

Я смущен и, вероятно, неправильно понимаю ваш вопрос.

Если у вас уже есть строка (вы можете вычислить хэш), зачем ее нужно ее восстановить?

Используете ли вы большую строку в качестве ключа для чего-то, возможно?

+0

Хорошая точка. Думаю, я не поняла. У меня есть строка, но я хочу получить другую связанную с ней информацию, которая хранится в БД. – Sruly

+0

Тогда почему бы вам не подумать об использовании чего-то другого, кроме строки, чтобы найти эти связанные вещи? Но в любом случае, я согласен с верхним ответом (атм), вы должны проверить и измерить. –

2

Первый - ИЗМЕРИТЕ его. Это единственный способ сказать наверняка.
Второе. Если у вас нет проблемы со скоростью поиска строки, тогда сохраните ее просто и не используйте хэш.

Однако для вашего фактического вопроса (и просто потому, что это интересная мысль). Это зависит от того, насколько похожи строки. Помните, что движку БД не нужно сравнивать все символы в строке, достаточно, чтобы найти разницу. Если вы просматриваете 10 миллионов строк, которые начинаются с тех же 300 символов, то хэш, скорее всего, будет быстрее. Если, однако, вы ищете единственную строку, которая начинается с x, тогда сравнение строк может быть быстрее. Я думаю, что хотя SQL все равно должен будет получить всю строку с диска, даже если он использует только первый байт (или первые несколько байтов для многобайтовых символов), поэтому общая длина строки будет по-прежнему иметь влияние.

Если вы пытаетесь сравнить хэш, вы должны сделать хэш индексированным вычисленным столбцом. Это не будет быстрее, если вы будете обрабатывать хэши для всех строк при каждом запуске запроса!

Вы также можете рассмотреть возможность использования функции CRC SQL. Он создает int, который будет еще быстрее компаре и быстрее вычисляется. Но вам придется дважды проверить результаты этого запроса, фактически проверив строковые значения, потому что функция CRC не предназначена для такого рода использования и гораздо более предпочтительна для возврата повторяющихся значений. Вам нужно будет выполнить проверку CRC или Hash в одном запросе, а затем внешний запрос, который сравнивает строки. Вы также захотите посмотреть, как генерируется QEP, чтобы оптимизатор обрабатывал запрос в том порядке, в котором вы планировали. Сначала он может сначала выполнить сопоставление строк, а затем CRC или Hash.

Как заметил кто-то другой, это только хорошо, если вы делаете точное совпадение. Хэш не может помочь, если вы пытаетесь выполнить какой-либо диапазон или частичное совпадение.

+0

Ну, хэш-значение - это число, поэтому всегда проще сравнивать одно число с другим числом, чем сравнивать строки. Даже в вашем примере единственной строки, начинающейся с x, все равно нужно сравнить значения Ascii. – DevinB

+0

Значение хэша не является одним числом, его varbinary. И не является ли значение ascii для x числом? – pipTheGeek

1

СОВЕТ: если вы собираетесь хранить хэш в базе, будет MD5 Hash всегда 16 байт, поэтому могут быть сохранены в столбце UniqueIdentifier (и System.Guid в .NET)

Это может предложить некоторый прирост производительности по сравнению с хэшами сохранения по-другому (я использую этот метод для проверки изменений двоичного/ntext-поля, но не для строк/nvarchars).

1

«Идеальный» ответ определенно да. Строковое сопоставление с индексированным столбцом всегда будет медленнее, чем сопоставление хэш-значения, хранящейся в столбце индекса. Это то, для чего предназначены хэш-значения, потому что они берут большой набор данных (например, 3000 точек сравнения, по одному на символ) и объединяют его в меньший набор данных (например, 16 точек сравнения, по одному на байт).

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

Однако, как уже отмечалось, реализация собственной оптимизированной функции хэширования опасна и, вероятно, не будет хорошо. (Я пробовал и терпел неудачу). Конфликты Хэша не являются особенно проблемой, потому что тогда вам просто придется отказаться от алгоритма соответствия строк, а это значит, что это будет (в худшем случае) точно так же быстро, как и метод сравнения строк.

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

И если вы хотите узнать о производительности, Just Measure It.

Смежные вопросы