2015-07-03 4 views
4

Это кажется странным вопросом. Я знаю разные типы индексов в sql-сервере (кластерный, некластеризованный, уникальный, отфильтрованный, индекс с включенными столбцами и т. Д.), И я знаю, как их создавать. Также я знаю, что индекс зависит от запроса, но я не знаю, кто выбирает столбец при создании индекса. Например, предположим, что простой веб-сайт позволяет пользователям публиковать текст и изображения. Сайт имеет простой две таблицы, изображенные на картинке:Как выбрать столбцы при создании индекса?

How to choose columns when creating index

запрос, получить пользователя в веб-сайт:

Select UserID,UserName from User where Email='something' and Password='something' 

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

Запрос, который получает сообщения пользователь:

Select * from Posts where UserID='something' 

Этот запрос отличается от первого запроса. Этот запрос может возвращать несколько строк, в то время как первый всегда будет возвращать одну строку. Теперь тот же вопрос, как выбрать столбец?

То, что я хочу сказать, как выбрать столбцы, когда:

  1. Создание кластерного индекса.
  2. Создание некластеризованного индекса.
  3. Создание некластеризованных включенных столбцов.

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

ответ

11

В идеальном мире вы хотите индексировать столбцы, которые фигурируют в пункте WHERE или JOIN. В вашем случае это будут Email и Password столбцы.

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

Так в значительной степени этот показатель:

CREATE NONCLUSTERED INDEX idx_User_Email_Password 
    ON dbo.User (Email, Password); 

Так что, если вы будете запускать этот запрос:

SELECT UserID, UserName 
FROM User 
WHERE Email = 'something' 
    AND Password = 'something'; 

Вы в конечном итоге, используя только что созданный индекс (скорее всего) или кластерный индекс, и он будет искать его. Тем не менее, ваш запрос выбирает UserID и UserName, которые не включены в ваш индекс, в результате ваш запрос будет выполнять поиск ключей (он найдет записи в созданном индексе и оглянется на вашу таблицу dbo.User, чтобы найти соответствующие значения для SELECT (UserID и UserName). Чтобы этого избежать, вы можете создать индекс с столбцами INCLUDED, чтобы удалить Key Lookup (и вы захотите это сделать).

CREATE NONCLUSTERED INDEX idx_User_Email_Password 
    ON dbo.User (Email, Password) 
    INCLUDE (UserID, UserName); 

Используя этот указатель, вы получите хороший поиск НЕПРЕРЫВНОЙ ИНДЕКСЫ в своем плане выполнения.

Также важно выбрать порядок индексированных столбцов. Скажем, ваша таблица будет содержать UserTypeID (их не так много). Таким образом, вы передали бы определенные идентификаторы UserTypeID и список UserID, тогда SQL Server, вероятно, захочет выбрать индекс, который имеет UserTypeID в качестве первого индексированного столбца.

Так некоторые тесты:

CREATE TABLE #Users 
(
    UserId INT 
    , UserName VARCHAR(500) 
    , Email VARCHAR(500) 
    , Password VARCHAR(500) 
); 

CREATE CLUSTERED INDEX idx_Users_UserID 
    ON #Users (UserID); 

-- Some test data from my DB 
INSERT INTO #Users (UserId, UserName, Email, Password) 
SELECT TOP (10000) UserId, UserName, Email, 'password' 
FROM Users; 

Так что это вопрос:

SELECT * 
FROM #Users; 

Это будет выполнять сканирование индекса, так как мы не указываем никаких подробностей. enter image description here

Теперь, если мы указываем UserId он будет искать ваш кластерный индекс (мы имеем UserId как ключ):

SELECT * 
FROM #Users 
WHERE UserID = 602; 

enter image description here

Теперь давайте создадим индекс без включенных столбцов и что-то запроса:

CREATE NONCLUSTERED INDEX idx_Users_Email_Password 
    ON #Users (Email, Password); 

SELECT * 
FROM #Users 
WHERE Email = '[email protected]'; 

Как я уже сказал, он использует созданный индекс и выполняет поиск ключей, он находит соответствие Ema il и пароль и находит остальные столбцы в таблице для вывода их (P.S. Если бы ouputting, скажем, только электронная почта, это не будет делать ключ поиска, он был бы не нужен): enter image description here

Теперь давайте создадим incex с включенным UserName и выполнения запроса выше. Он будет производить это хороший план выполнения с простым индексом NONCLUSTERED искать, как я говорил вам раньше:

CREATE NONCLUSTERED INDEX idx_Users_Email_Password_iUserName 
    ON #Users (Email, Password) 
    INCLUDE (UserName); 

enter image description here

Это высококачественное изделие, и я бы рекомендовал читать его: https://www.simple-talk.com/sql/performance/index-selection-and-the-query-optimizer/

+0

Для запроса: SELECT UserID, UserName От пользователя WHERE Email = 'something' AND Password = 'something'; Как вы говорите, мы можем индексировать электронную почту и пароль, а также включать идентификаторы пользователя и имя пользователя в столбцы, включенные в индекс. Если UserID индексируется с помощью кластерного индекса, нужно ли включать идентификатор пользователя в качестве включенного столбца в некластеризованный индекс? Что происходит здесь для ключевого поиска? –

+1

Если 'UserID' - ваш кластерный индекс, вы не должны его включать. Вы можете попробовать оба. –

+0

Но для выполнения поиска по-прежнему необходимо выполнить поиск ключа, чтобы найти UserName. Что я говорю правду? –

0

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

+0

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

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