Обе таблицы имеют одинаковую структуру и 19972 строки в каждой таблице. для практики индексации я создал обе таблицы, имеющие одинаковую структуру, и создал
clustered index on persontb(BusinessEntityID)
а также
nonclustered index on Persontb_NC(BusinessEntityId)
и структура таблицы
BusinessEntityID int
FirstName varchar(100)
LastName varchar(100)
-- Nonclusted key on businessentityid takes 38%
SELECT BusinessEntityId from Persontb_NC
WHERE businessentityid BETWEEN 400 AND 4000
-- CLustered key businessentityid takes 62%
SELECT BusinessEntityId from persontb
WHERE businessentityid BETWEEN 400 AND 4000
Почему кластерный индекс занимает 62%, а не кластерный 38%?
Ответы:
Да, кластеризованный индекс имеет меньше строк на страницу, чем некластеризованный индекс, поскольку конечные страницы кластерного индекса должны хранить значения для двух других столбцов (
FirstName
иLastName
).Листовые страницы NCI хранят только
BusinessEntityId
значения и локатор строк (RID, если таблица является кучей, или ключ CI в противном случае).Таким образом, предполагаемые затраты отражают большее количество операций чтения и ввода-вывода.
Если бы вы объявили NCI как
тогда это будет похоже на кластерный индекс.
источник
Кластерный индекс содержит не только данные из столбца индекса, но и данные из всех других столбцов. (В таблице может быть только один кластерный индекс)
Некластеризованный индекс содержит только данные из индексированных столбцов и указатель row_id, где находятся остальные данные.
Поэтому этот конкретный некластеризованный индекс легче, и для его сканирования / поиска требуется меньше чтения, и этот конкретный запрос будет работать быстрее.
Однако, если бы вы попытались получить FirstName и LastName, это было бы по-другому, и кластерный индекс должен работать лучше.
источник
Процент между планами запросов не имеет смысла сравнивать напрямую. Вы должны сравнить запросы, чтобы иметь правильное сравнение. Кроме того, небольшое количество строк имеет тенденцию скрывать различия в производительности между стратегиями индексирования. Увеличив количество строк до 10 миллионов, вы сможете получить более четкую картину различий в производительности.
Существует пример сценария, который создает 3 таблицы: две таблицы сверху и третью с кластеризованным и некластеризованным индексом.
Заполните таблицы 10 миллионами строк
Мы можем использовать sys.dm_db_index_physical_stats, чтобы увидеть размер на диске индексов.
И результаты:
Кластерный индекс T1 составляет около 1,6 ГБ. Некластеризованный индекс T2 составляет 170 МБ (90% экономии на вводе-выводе). Некластеризованный индекс T3 составляет 97 МБ, или примерно на 95% меньше IO, чем T1.
Таким образом, исходя из требуемого ввода-вывода, исходный план запроса должен был составлять примерно 10% / 90%, а не 38% / 62%. Кроме того, поскольку некластеризованный индекс, вероятно, полностью умещается в памяти, разница может быть еще больше, поскольку дисковый ввод-вывод очень дорогой.
источник
10%/90%
фигура является более точной, чем38%/62%
. Строки длиной от 100 до 200, безусловно, будут чрезмерно завышать требования к пространству для пары имя / фамилия, поэтому плотность страниц будет ниже, чем у OP. Когда я пытаюсь сопоставить данные вашего примера, предполагаемые затраты составляют 87% / 13% .data_pages
инsys.allocation_units
. Вы можете увидеть это изCREATE TABLE T1(C INT);CREATE TABLE T2(C INT);UPDATE STATISTICS T1 WITH PAGECOUNT = 1;UPDATE STATISTICS T2 WITH PAGECOUNT = 100
сравнения сметных расходовSELECT * FROM T1;SELECT * FROM T2;