У меня есть следующий запрос:SQL Index Question: Почему SQL Server предпочитает этот индекс NONCLUSTERED для CLUSTERED?
SELECT
COUNT(*)
FROM
FirstTable ft
INNER JOIN SecondTable st ON ft.STID = st.STID
Как вы можете догадаться, «STID» является первичным ключом на «SecondTable» ... и «FirstTable» будет иметь указатель на эту вторую таблицу. Вот показатели, которые у меня есть:
FirstTable: NONCLUSTERED INDEX на колонке "STID"
SecondTable: CLUSTERED PRIMARY KEY
INDEX на "STID"
Приведенный выше запрос дает мне стоимость поддерева 19.90 и принимает 2 секунды.
После запуска советника по настройке базы данных для этого запроса они предложили сделать очень похожим индексом, который у меня был на второй таблице ... но некластеризован. Итак, я попробовал это с этими результатами.
FirstTable: NONCLUSTERED INDEX на колонке "STID"
SecondTable: NONCLUSTERED
INDEX на "STID"
Теперь, выше запрос дает мне стоимость поддерева 10,97 и принимает < 1 второй!
Этот 100% разрушает мой мозг ... Почему индекс NONCLUSTERED работает быстрее, чем индекс CLUSTERED в этом сценарии?
Это было быстро! - Это именно тот ясный, логичный ответ, который я искал. - Конечно, это не мой * реальный * запрос, но он действительно помогает моему реальному запросу (который не использовал столбцы из этой таблицы, а просто использовал его для внутреннего соединения/фильтра) - Thx! –
@Quassnoi: извините, этот ответ для меня не имеет смысла. Вы сказали: «с кластеризованным индексом он должен присоединиться к таблице». Кластеризованный индекс - это индекс. Исходный запрос на самом деле не извлекает какой-либо столбец, поэтому все, что ему нужно, должно соответствовать значениям ключа, то есть нужно сканировать только страницы индекса. Если вы посмотрите на эти фотографии, https://technet.microsoft.com/en-us/library/ms177443%28v=sql.105%29.aspx и https://technet.microsoft.com/en-us/library /ms177484%28v=sql.105%29.aspx, разница в том, что в кластерном индексе у вас есть данные в листовых узлах, но запрос не нужно идти на уровень листа. – costa
@quassnoi: продолжить ... если не использовать * что-то делает для оптимизатора запросов, и лучше использовать count (1). Основываясь на моем опыте работы с SQL Server, особенно 2008 и 2008 R2, заключается в том, что иногда он делает эти мозговые мертвые вещи, которых вы никогда не ожидали. – costa