Есть ли какое-либо преимущество в создании кластеризованного индекса, если мы не собираемся запрашивать/искать записи на основе этого столбца?

Я делаю обзор некоторых таблиц БД, которые были созданы в нашем проекте, и наткнулся на это. Таблица содержит столбец Identity (ID), который является первичным ключом для таблицы, и кластеризованный индекс был определен с использованием этого столбца ID. Но когда я смотрю на SPROC, который извлекает записи из этой таблицы, я вижу, что столбец ID никогда не используется в запросе, и они запрашивают записи на основе столбца USERID (этот столбец не уникален), и может быть несколько записей для тот же USERID.

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


person Isaiah4110    schedule 14.08.2017    source источник
comment
Столбец PK, скорее всего, является целью нескольких JOIN, которые получат большую прибыль от кластеризованного индекса.   -  person Alejandro    schedule 14.08.2017


Ответы (2)


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

Между прочим, это разные понятия. Первичный ключ — это проблема моделирования данных, логическая концепция. Индекс - это проблема физического дизайна. СУБД SQL должна поддерживать первичные ключи, но не должна иметь индексов, кластеризованных или отсутствующих.

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

Если никакая комбинация столбцов не представляет собой уникальный идентификатор, у вас есть логическая проблема, а именно: что означает строка? Какой аспект реального мира он представляет?

Основной принцип реляционной модели заключается в том, что элементы в отношении (строки в таблице) уникальны, и каждый из них идентифицирует что-то. Если две строки идентичны, они обозначают одно и то же. Что значит удалить один из них? То, что они оба идентифицируют, все еще там или нет? Если да, то какой цели служил второй ряд?

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

person James K. Lowden    schedule 14.08.2017

Если столбец IDENTITY никогда не используется в предложениях WHERE и JOIN или на него ссылаются внешние ключи, возможно, USERID должен быть кластеризованным первичным ключом. В этом случае я бы вообще поставил под сомнение необходимость столбца ID.

Лучший выбор для кластерного индекса во многом зависит от того, как запрашивается таблица. Если большинство запросов выполняется по USERID, то, вероятно, это должен быть уникальный кластеризованный индекс (или кластеризованное уникальное ограничение) и некластеризованный столбец ID.

Имейте в виду, что ключ кластеризованного индекса неявно включен во все некластеризованные индексы в качестве локатора строк. Подразумевается, что некластеризованные индексы могут с большей вероятностью охватывать запросы, и в результате страницы конечных узлов некластеризованного индекса становятся шире.

person Dan Guzman    schedule 14.08.2017
comment
Вот мои опасения по поводу добавления USERID в качестве кластеризованного индекса: 1. SQL-сервер будет добавлять уникальный файл, чтобы сделать индекс уникальным. Я читал, что это может быть ограничение производительности? 2. Также может быть много добавлений/удалений UID - не будет ли это проблемой, когда это кластеризованный индекс? - person Isaiah4110; 14.08.2017
comment
Я думал, что USERID уникален. В этом случае SQL Server не добавит уникальный идентификатор. Я не знаю, что uniquifier вызывает проблемы с производительностью, кроме 4 байтов дополнительного хранилища. Ключи инкрементного кластеризованного индекса имеют как плюсы, так и минусы в отношении производительности вставки. Короткий ответ: я бы не слишком беспокоился о производительности неинкрементных ключей, если только вы не используете вращающиеся носители с несколькими шпинделями и не ожидаете сотни миллионов пользователей. - person Dan Guzman; 14.08.2017