Индексы хэша SQL Server

При использовании типа столбца CHECKSUM для искусственного создания хэш-индекса, действительно ли поиск выполняется O (1) или все еще O (lg n), как для кластеризованного индекса? У меня есть таблица, из которой я буду выбирать на основе ее столбца идентификатора, и мне нужно, чтобы поиск был как можно быстрее, поэтому кластерный индекс является самым быстрым из возможных вариантов? Я ищу что-то, что обеспечит производительность O (1).

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
10
0
10 397
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Нет никаких преимуществ при поиске индексированной контрольной суммы по кластеризованному индексу в поле идентификатора, если поле идентификатора имеет тип int, поскольку оба будут выполнять поиск по кластеризованному индексу. Кроме того, CHECKSUM столбца int всегда возвращает то же значение, что и столбец (то есть CHECKSUM (535) = 535). Однако поиск CHECKSUM обычно работает лучше, если идентификатор представляет собой столбец из длинных символов.

так есть ли способ добиться лучшей производительности, чем кластерный индекс? Кластерный индекс по-прежнему O (lg n), и я искал O (1) ..

eulerfx 25.11.2008 22:12
Ответ принят как подходящий

Хорошо, 2 балла. Функция SQL CHECKSUM не создает хеш-значение. Фактически он вычисляет значение CRC. Это не очень хороший кандидат для проверки хэша, потому что будет относительно большое количество коллизий. Вы должны проверить функцию hash_bytes, если вам нужна хеш-функция. Во-вторых, вы фактически не создаете хеш-индекс. Вы создаете обычное b-дерево на основе хеш-значения, поэтому время поиска будет точно таким же, как и для любого другого индекса b-дерева для типа данных аналогичного размера. Есть шанс, что вы можете немного повысить производительность, используя CRC или хэш длинного значения varchar, чтобы позволить сравнения меньшего числа байтов, но сравнение строк проверяет только столько байтов, сколько нужно, что составляет первый символ, который не совпадает, и если вы действительно соответствуете хешированному значению, вам все равно нужно дважды проверить фактическое значение. Поэтому, если у вас нет много очень похожих строк, вы, вероятно, в конечном итоге сравните БОЛЬШЕ байтов, используя хэш (или CRC).

Короче говоря, я не думаю, что это разумный план, но, как и все оптимизации, вы должны протестировать его в своем конкретном случае, а затем принять решение. Мне было бы интересно увидеть ваши результаты, если вы захотите их опубликовать. И я не верю, что существует более быстрый способ найти строку на SQL-сервере, чем использование кластерного индекса.
Если вам интересно, Ingres (от CA) может создавать хеш-индексы, которые затем будут иметь значение O (1). могут быть и другие RDBM, которые также поддерживают истинные хеш-индексы.

Я не согласен. CRC должны быть довольно случайными после того, как вы измените его часть на количество сегментов. Я не понимаю, почему вы думаете, что будет «относительно большое количество столкновений».

lkessler 30.11.2008 06:12

Для теста я просто проверил наличие коллизий в столбце из 11 тыс. Строк (в основном URL-адреса, поэтому много одинаковых начальных сегментов). С BINARY_CHECKSUM я получил 3 трехсторонних столкновения и 5 двусторонних столкновений. С HASHBYTES у меня ничего не было, как и следовало ожидать, даже с использованием MD2.

Steve Jessop 03.08.2010 21:31

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

В общем, я бы не стал создавать искусственный столбец хеширования, если вы не выполняете точные совпадения с потенциально большими строками или двоичными двоичными объектами (как упоминает pipTheGeek). Я просто хотел добавить, что иногда это необходимо, поскольку строки могут быть слишком большими, чтобы поместиться в индексный ключ. Существует ограничение на размер индексных ключей, я думаю, 2k для SQL Server.

Конечно, в ваше соединение вам необходимо включить столбец хэша и столбец источника, чтобы разрешить любые неоднозначности, возникающие в результате хеширования.

SQL Server имеет Лимит 900 байт для максимального общего размера всех столбцов ключа индекса.

Tim Lehner 13.02.2013 02:32

Я не думаю, что у SQL-сервера изначально есть индекс на основе хеш-таблицы. Документация BOL говорит о построении стандартного (древовидного) индекса на основе вычисленного значения. Это не то же самое, что Линейная хеш-таблица, которая представляет собой структуру индекса, доступную на некоторых платформах СУБД, но не на SQL Server (AFAIK).

Вы можете получить некоторую выгоду от использования техники, описанной в это сообщение в блоге, для хеширования больших строковых значений, таких как URL-адреса, для более быстрого поиска. Однако базовый индекс по-прежнему представляет собой древовидную структуру и равен O (Log N).

ОБНОВЛЕНИЕ: таблицы SQL Server в памяти действительно имеют возможность индексации на основе хэш-таблицы.

Dave Markle 13.05.2016 00:11

Другие вопросы по теме