Жесткое и быстрое правило для включения столбцов в индекс

Есть ли какое-либо жесткое и быстрое правило, чтобы определить, какие столбцы и в каком порядке он должен быть включен. Включено в некластеризованный индекс. Я просто читал этот пост https://stackoverflow.com/вопросы /1307990 /почему потребительной заместитель включают придаточного-при создающей-ан-индекс и я нашел, что для следующего запроса:

SELECT EmployeeID, DepartmentID, LastName
FROM Employee
WHERE DepartmentID = 5

Плакат предложил сделать такой индекс:

CREATE NONCLUSTERED INDEX NC_EmpDep 
  ON Employee(EmployeeID, DepartmentID)
  INCLUDE (Lastname)

вот мой вопрос, почему мы не можем сделать такой индекс

CREATE NONCLUSTERED INDEX NC_EmpDep 
      ON Employee( EmployeeID, DepartmentID, LastName)

или

    CREATE NONCLUSTERED INDEX NC_EmpDep 
          ON Employee( EmployeeID, LastName)
INCLUDE (DepartmentID)

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

35 голосов | спросил Rocky Singh 31 Maypm11 2011, 16:57:19

4 ответа


42

Это предложение индекса marc_s неверно. Я добавил комментарий. (И это был мой ответ принят тоже!)

Индекс для этого запроса будет

CREATE NONCLUSTERED INDEX NC_EmpDep 
  ON Employee(DepartmentID)
  INCLUDE (Lastname, EmployeeID)

Индекс обычно

CREATE INDEX <name> ON <table> (KeyColList) INCLUDE (NonKeyColList)

Где:

  • KeyColList = Ключевые столбцы = используется для ограничения и обработки строк
    WHERE, JOIN, ORDER BY, GROUP BY и т. Д.
  • NonKeyColList = Non-key columns = используется в SELECT и агрегации (например, SUM (col)) после выбора /ограничения
ответил gbn 31 Maypm11 2011, 17:08:06
17

JNK и gbn дали отличные ответы, но также стоит рассмотреть общую картину - не просто сосредоточиться на одном запросе. Хотя этот конкретный запрос может извлечь выгоду из индекса (# 1):

Employee(DepartmentID) INCLUDE (Lastname, EmployeeID)

Этот индекс вообще не помогает, если запрос немного меняется, например:

SELECT EmployeeID, DepartmentID, LastName
FROM Employee
WHERE DepartmentID = 5 AND LastName = 'Smith'

Для этого понадобится индекс (# 2):

Employee(DepartmentID, LastName) INCLUDE (EmployeeID)

Представьте, что у вас было 1000 сотрудников в отделе 5. Используя индекс №1, чтобы найти всех Смитов, вам нужно искать все 1000 строк в отделе 5, поскольку включенные столбцы не являются частью ключа. Используя индекс № 2, вы можете напрямую обратиться к Департаменту 5, LastName Smith.

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


В качестве примечания следует отметить, что если EmployeeID был ключом кластеризации для этой таблицы - при условии кластеризованного индекса - тогда вам не нужно включать EmployeeID - он присутствует во всех некластеризованных индексах, что означает индекс # 2 может быть просто

Employee(DepartmentID, LastName)
ответил 31 Maypm11 2011, 17:33:35
6

Я не уверен, как вы получили этот первый. Для меня для этого запроса я бы использовал:

CREATE NONCLUSTERED INDEX NC_EmpDep 
  ON Employee(DepartmentID)
  INCLUDE (EmployeeID, Lastname)

Не существует «жесткого и быстрого правила» для почти ничего в SQL.

Но для вашего примера единственным полем, которое будет использоваться индекс, является DepartmentID, потому что он находится в предложении WHERE.

Другие поля должны быть легко доступны оттуда. Вы выбираете на основе DepartmentID, тогда INCLUDE имеет эти поля в листовом узле индекса.

Вы не хотите использовать другие примеры, потому что они не будут работать для этого индекса.

Подумайте об индексе, таком как телефонная книга. Большинство телефонных книг заказываются по Фамилия, Имя, Среднее Начальное. Если вы знаете чье-то имя, но не фамилию, телефонная книга вам не подходит, поскольку вы не можете найти имя, основанное на указателе индекса телефонной книги.

Поля INCLUDE напоминают номер телефона, адрес и т. д. другую информацию для каждой записи в книге.

EDIT:

Чтобы уточнить, почему не использовать:

CREATE NONCLUSTERED INDEX NC_EmpDep 
          ON Employee( EmployeeID, LastName)
INCLUDE (DepartmentID)

Этот индекс полезен, если у вас есть EmployeeID или BOTH EmployeeID и LastName в вашем WHERE. Это в значительной степени OPPOSITE того, что вам нужно для этого запроса.

ответил JNK 31 Maypm11 2011, 17:08:30
0

Я думаю, что вы все равно сможете использовать индекс (employee_id, department_id), но вам придется включить строку «фиктивный» в фразе, например:  "employee_id = employee_id)

  • с индексом on (employee_id, dedemnent_id),
  • нужно искать /ограничивать только на department_id
  • зная, что он не будет использовать индекс, так как неправильный порядок (или что-то изменилось к настоящему времени, и следующий «трюк» больше не нужен. Я «старая»?) .
  • Использовать «старый» tricK?

    выберите * from Employee emp
    где emp.employee_id = emp.employee_id
      и emp.department_id = 5

(Таким образом, я не фокусируюсь на включенной здесь части Lastname, но на кнопке yes /или не используется.)

С уважением,

Miguell

ответил Miguel Leeuwe 28 Mayam15 2015, 00:46:08

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132