Делает ли создание индекса по текстовому столбцу поиск более дорогим? - PullRequest
0 голосов
/ 28 февраля 2019

Влияет ли наличие строкового столбца в качестве первичного ключа вместо целочисленного столбца отрицательно на время поиска и / или время вставки?

Сценарии

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

Это имя пользователя уже существует или оно взято кем-то другим?

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

Существует ли строка с этим UserName в таблице User?

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

Существует ли строка с этим Email в таблице User?

д.Только в случае связывания таблицы User с другими пользовательскими таблицами, такими как UserRole, UserClaim и т. Д., Нам может потребоваться объединить их на основе целого числа Id, например, так:

  SELECT * 
  FROM User, UserClaim
  WHERE User.Id = UserClaim.UserId;

Наличие целого числа в качестве первичного ключа и наличие строки в качестве первичного ключа

До сих пор у меня всегда была только пользовательская таблица с целым числомпервичный ключ (и кластеризованный индекс по нему), например, так:

User
-----
Id int primary key identity(1, 1),
UserName nvarchar(50) not null,
Email nvarchar(100) not null,
PasswordHash nvarchar(32) not null

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

User
-----
UserName nvarchar(50) primary key,
Email nvarchar(100) not null,
PasswordHash nvarchar(32) not null

Это создаст кластеризованный индекс в поле UserName, что, вероятно, ускорит запросы в сценариях a и b , перечисленных выше, но я не уверен в сценариях воздействия c и d , поскольку это будет зависеть от скорости или сравнения целых чиселсо скоростью сравнения показателей баsed на строковом столбце.

Вопросы

Тем не менее, это оставляет меня с несколькими потерянными концами, мне нужно связать, прежде чем я смогу совершить на этом проекте:

  1. Имеет ли создание кластеризованного индекса для текстового поля, как указано выше, какие-либо последствия для производительности?Как это влияет на время вставки?Время поиска?

    Я мог бы представить, что создание индекса для целого числа быстрее, чем для строки?

  2. У нас может быть только один кластерный индекс.Если я позволю своим пользователям входить в систему, используя имя пользователя или электронную почту, кого угодно, то мне придется выполнять поиск по полям UserName и Email так же часто.Как мне это сделать?Должен ли я создавать некластеризованный индекс для поля Email?

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

    SELECT * FROM User, UserRole
    WHERE User.UserName = UserRole.UserName;
    
  4. Учитывая # 3, похоже, что я должен просто сохранить целочисленный столбец Id в таблице User и создать некластеризованный индекс каждый настолбцы UserName и Email?

Я использую Microsoft SQL Server 2014.

1 Ответ

0 голосов
/ 28 февраля 2019

Влияет ли создание кластеризованного индекса на текстовое поле, как указано выше, на производительность?Как это влияет на время вставки?Время поиска?

  • Каждая строка каждого некластеризованного индекса будет содержать ключ кластеризованного индекса как ключ строки.INT = 4 bytes, ваш строковый столбец Unicode Email может потенциально занимать NVARCHAR(100) = up to 200 bytes.
  • Кластерные индексы хороши для сканирования диапазона.Сканирование диапазона адресов электронной почты вряд ли ожидается.
  • Кластерный индекс на основе идентификаторов является гарантией, близкой к нулю фрагментации и быстрой вставке, из-за отсутствия разбиения страниц

У нас может быть только один кластерный индекс.Если я позволю своим пользователям входить в систему, используя имя пользователя или электронную почту, кого угодно, то мне придется выполнять поиск по полям UserName и Email так же часто.Как мне это сделать?Должен ли я создать некластеризованный индекс в поле «Электронная почта»?

Да, если вы решите создать уникальный кластеризованный индекс для UserName, вам понадобится другой некластеризованный индекс для Email.Если пользователь будет выполнять поиск по столбцу Email, имя пользователя столбца будет частью такого индекса автоматически (по причине, описанной в пункте выше), и такой индекс будет охватываться.

Будет иметьСтолбец string в качестве первичного ключа влияет на производительность объединений

Кластерный индекс для столбца UserName оптимален для таких объединений, поскольку он будет сохранять данные предварительно упорядоченными, поэтому вместо этого для больших наборов данных *Скорее всего, 1030 * объединений будут заменены на MERGE объединений

Учитывая # 3, похоже, что я должен просто сохранить столбец целочисленного идентификатора в таблице User и каждый раз создавать некластеризованный индексв столбцах UserName и Email?

Это очень сильно зависит от вашей рабочей нагрузки.Если вам часто приходится присоединяться к этой таблице в столбце UserName, может оказаться, что кластерный индекс для такого столбца будет работать для вас.В этом случае вы можете создать некластеризованный уникальный индекс для поля Email и оставить первичный ключ на ID, но сделать его и некластеризованным

(Этот пост в значительной степени основан на личныхмнение)

...