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





Нет никаких преимуществ при поиске индексированной контрольной суммы по кластеризованному индексу в поле идентификатора, если поле идентификатора имеет тип int, поскольку оба будут выполнять поиск по кластеризованному индексу. Кроме того, CHECKSUM столбца int всегда возвращает то же значение, что и столбец (то есть CHECKSUM (535) = 535). Однако поиск CHECKSUM обычно работает лучше, если идентификатор представляет собой столбец из длинных символов.
Хорошо, 2 балла.
Функция SQL CHECKSUM не создает хеш-значение. Фактически он вычисляет значение CRC. Это не очень хороший кандидат для проверки хэша, потому что будет относительно большое количество коллизий. Вы должны проверить функцию hash_bytes, если вам нужна хеш-функция.
Во-вторых, вы фактически не создаете хеш-индекс. Вы создаете обычное b-дерево на основе хеш-значения, поэтому время поиска будет точно таким же, как и для любого другого индекса b-дерева для типа данных аналогичного размера.
Есть шанс, что вы можете немного повысить производительность, используя CRC или хэш длинного значения varchar, чтобы позволить сравнения меньшего числа байтов, но сравнение строк проверяет только столько байтов, сколько нужно, что составляет первый символ, который не совпадает, и если вы действительно соответствуете хешированному значению, вам все равно нужно дважды проверить фактическое значение. Поэтому, если у вас нет много очень похожих строк, вы, вероятно, в конечном итоге сравните БОЛЬШЕ байтов, используя хэш (или CRC).
Короче говоря, я не думаю, что это разумный план, но, как и все оптимизации, вы должны протестировать его в своем конкретном случае, а затем принять решение. Мне было бы интересно увидеть ваши результаты, если вы захотите их опубликовать. И я не верю, что существует более быстрый способ найти строку на SQL-сервере, чем использование кластерного индекса.
Если вам интересно, Ingres (от CA) может создавать хеш-индексы, которые затем будут иметь значение O (1). могут быть и другие RDBM, которые также поддерживают истинные хеш-индексы.
Я не согласен. CRC должны быть довольно случайными после того, как вы измените его часть на количество сегментов. Я не понимаю, почему вы думаете, что будет «относительно большое количество столкновений».
Для теста я просто проверил наличие коллизий в столбце из 11 тыс. Строк (в основном URL-адреса, поэтому много одинаковых начальных сегментов). С BINARY_CHECKSUM я получил 3 трехсторонних столкновения и 5 двусторонних столкновений. С HASHBYTES у меня ничего не было, как и следовало ожидать, даже с использованием MD2.
Вы можете попробовать настроить все для использования хэш-соединения, вы можете посмотреть план выполнения, чтобы убедиться, что хеш-соединение действительно используется. Когда используются хэш-соединения, SQL Server по-прежнему сначала создает хеш-таблицу как часть выполнения отдельного запроса. Я считаю, что индексы никогда не хранятся в виде хэшей, только в виде деревьев.
В общем, я бы не стал создавать искусственный столбец хеширования, если вы не выполняете точные совпадения с потенциально большими строками или двоичными двоичными объектами (как упоминает pipTheGeek). Я просто хотел добавить, что иногда это необходимо, поскольку строки могут быть слишком большими, чтобы поместиться в индексный ключ. Существует ограничение на размер индексных ключей, я думаю, 2k для SQL Server.
Конечно, в ваше соединение вам необходимо включить столбец хэша и столбец источника, чтобы разрешить любые неоднозначности, возникающие в результате хеширования.
SQL Server имеет Лимит 900 байт для максимального общего размера всех столбцов ключа индекса.
Я не думаю, что у SQL-сервера изначально есть индекс на основе хеш-таблицы. Документация BOL говорит о построении стандартного (древовидного) индекса на основе вычисленного значения. Это не то же самое, что Линейная хеш-таблица, которая представляет собой структуру индекса, доступную на некоторых платформах СУБД, но не на SQL Server (AFAIK).
Вы можете получить некоторую выгоду от использования техники, описанной в это сообщение в блоге, для хеширования больших строковых значений, таких как URL-адреса, для более быстрого поиска. Однако базовый индекс по-прежнему представляет собой древовидную структуру и равен O (Log N).
ОБНОВЛЕНИЕ: таблицы SQL Server в памяти действительно имеют возможность индексации на основе хэш-таблицы.
так есть ли способ добиться лучшей производительности, чем кластерный индекс? Кластерный индекс по-прежнему O (lg n), и я искал O (1) ..