|
Вопрос по использованию индексов в запросе
|
|||
---|---|---|---|
#18+
Добрый день. Помогите, пожалуйста, разобраться в логике использования индексов 1. Есть таблица Id int CustomerId int Name nvarchar(100) ..... (несколько других полей) 2. Есть кластерный PK по Id 3. Есть индекс по CustomerId. Пробуем два варианта запроса: 1. SELECT * FROM [Table] where CustomerId = 1 Execution plan показывает, что идёт Clastered index scan. 2. SELECT * FROM [Table] where id in (SELECT[Id] FROM [Table] where CustomerId = 233365) Execution plan показывает, что идут два Index seek (по CustomerId и по PK), потом Nested loops. Собственно, вопросы - почему в первом случае не используется индекс по полю? - станет ли MS Sql его использовать при большом количестве записей? - нужно ли как-то форсировать использование индекса или всё равно не сделю лучше, чем разработчики Ms SQL и в нужный момент будет автоматически лучший путь выборки? Заранее спасибо, я больше бэкенд программист, чем SQL эксперт, в таких вещах разбираюсь неважно. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.06.2021, 15:50 |
|
Вопрос по использованию индексов в запросе
|
|||
---|---|---|---|
#18+
Sergey Gusev Добрый день. - почему в первом случае не используется индекс по полю? потому что вы выбираете все поля (select * ) а таких поле в некластерном индексе нет, поэтому оптимизатор считает что скан кластерного индекса будет дешевле если перепишите запрос на Код: sql 1.
получите поиск. не используйте никогда select * при тестах, выбирайте только те поля которые в действительности вам нужны Дополню: если строк в таблице мало или по гистограмме видно что предикат не будет особенно селективен оптимизатор все равно может посчитать что скан будет дешевле. По большей мере оптимизатор строит предположения на основе статистики, держите ее в актуальном состоянии. Вы всегда можете зафорсировать подсказку, но это требуется в исключительных вариантах. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.06.2021, 16:06 |
|
Вопрос по использованию индексов в запросе
|
|||
---|---|---|---|
#18+
felix_ff Sergey Gusev Добрый день. - почему в первом случае не используется индекс по полю? потому что вы выбираете все поля (select * ) а таких поле в некластерном индексе нет, поэтому оптимизатор считает что скан кластерного индекса будет дешевле если перепишите запрос на Код: sql 1.
получите поиск. не используйте никогда select * при тестах, выбирайте только те поля которые в действительности вам нужны второй запрос автора вручную реализует механизм key lookup. Sergey Gusev - почему в первом случае не используется индекс по полю? Как уже сказали, ваш индекс не содержит всех нужны для запроса данных, и при его использовании получится ровно тот план, что вы видите во втором случае. Sergey Gusev - станет ли MS Sql его использовать при большом количестве записей? Да Sergey Gusev - нужно ли как-то форсировать использование индекса или всё равно не сделю лучше, чем разработчики Ms SQL и в нужный момент будет автоматически лучший путь выборки? "Зависит от" Для вашего первого запрос при таких индексах хинт (forceseek) вряд ли навредит. Код: sql 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
10.06.2021, 16:14 |
|
Вопрос по использованию индексов в запросе
|
|||
---|---|---|---|
#18+
felix_ff не используйте никогда select * при тестах, выбирайте только те поля которые в действительности вам нужны Мне как раз нужны все поля в конечном результате. И я сейчас в размышлениях - делать ли самостоятельную выборку сначала id по простому индексу, а потом все поля по кластерному. Или это будет напрасной тратой усилий и оптимизатор запросов MS SQL решит эту проблему за меня. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.06.2021, 16:15 |
|
Вопрос по использованию индексов в запросе
|
|||
---|---|---|---|
#18+
Sergey Gusev felix_ff не используйте никогда select * при тестах, выбирайте только те поля которые в действительности вам нужны Мне как раз нужны все поля в конечном результате. И я сейчас в размышлениях - делать ли самостоятельную выборку сначала id по простому индексу, а потом все поля по кластерному. Или это будет напрасной тратой усилий и оптимизатор запросов MS SQL решит эту проблему за меня. тогда вы возможно неудачно выбрали ключ кластеризации. если нужны все поля делайте или кластерный индекс по [CustomerId] или модифицируйте свой некластерный индекс что бы он покрывал запрос, (используя INCLUDE список полей которые будут участвовать в конечном селекте) ... |
|||
:
Нравится:
Не нравится:
|
|||
10.06.2021, 16:19 |
|
Вопрос по использованию индексов в запросе
|
|||
---|---|---|---|
#18+
msLex Для вашего первого запрос при таких индексах хинт (forceseek) вряд ли навредит. Вот спасибо, добрый человек! Поставил - и прямо всё как хотел - Index seek и Key lookup ... |
|||
:
Нравится:
Не нравится:
|
|||
10.06.2021, 16:19 |
|
Вопрос по использованию индексов в запросе
|
|||
---|---|---|---|
#18+
Sergey Gusev msLex Для вашего первого запрос при таких индексах хинт (forceseek) вряд ли навредит. Вот спасибо, добрый человек! Поставил - и прямо всё как хотел - Index seek и Key lookup Любой Key Lookup / RID Lookup относительно дорогая операция, старайтесь как раз их избегать. На малом объеме возвращаемых данных вы особо не увидите накладных расходов, а когда объемы данных подрастут то вернуть к примеру набор в 100000 строк с использованием Key/RID Lookup уже будет достаточно наглядно видно что показывает оверхед по статистики IO ... |
|||
:
Нравится:
Не нравится:
|
|||
10.06.2021, 16:21 |
|
Вопрос по использованию индексов в запросе
|
|||
---|---|---|---|
#18+
felix_ff Любой Key Lookup / RID Lookup относительно дорогая операция А я думал, это даже луче, чем Index Seek. Получается, мой второй вариант (из стартового сообщения) - оптимальный? Там два Index seek. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.06.2021, 16:27 |
|
Вопрос по использованию индексов в запросе
|
|||
---|---|---|---|
#18+
Sergey Gusev felix_ff Любой Key Lookup / RID Lookup относительно дорогая операция А я думал, это даже луче, чем Index Seek. Получается, мой второй вариант (из стартового сообщения) - оптимальный? Там два Index seek. Физически это одно и тоже. Range Scan (все записи из индекса по заданному CustomerId) - 1 "спуск по дереву" По каждой из полученных записей поиск в кластерном индексе - N "спусков по дереву" Надо понимать, что каждый единичный index seek, это random IO, а перебор записей одной за другой - это последовательное чтенье (в том числе в рамках одной страницы) с read ahead вычиткой страниц. Что будет быстрее в конкретном случае - вопрос. В SQL Server заложены некие эмпирические оценки этих операций. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.06.2021, 16:36 |
|
Вопрос по использованию индексов в запросе
|
|||
---|---|---|---|
#18+
Sergey Gusev felix_ff Любой Key Lookup / RID Lookup относительно дорогая операция А я думал, это даже луче, чем Index Seek. Получается, мой второй вариант (из стартового сообщения) - оптимальный? Там два Index seek. Ну держите Вам тест для игры, можете сами поиграться с вариантами выборок. Можете даже отдельно запустить после наполнения таблиц скоп селектов с выводом актуального плана, он там петухов в процентном соотношении посчитает и покажет что будет более менее наглядно показывать картину. Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90.
а еще можете поиграться с самой выборкой и к примеру из select *, сделать выборку где не будет выбираться колонка [comment] и циферки начнут изменяться ... |
|||
:
Нравится:
Не нравится:
|
|||
10.06.2021, 16:53 |
|
Вопрос по использованию индексов в запросе
|
|||
---|---|---|---|
#18+
felix_ff Ну держите Вам тест для игры, можете сами поиграться с вариантами выборок. Спасибо, как раз сейчас сам это сделал. Добавил 4.7 миллионов записей и попробовал запросы из своего первого сообщения. Первый запрос перестал быть IndexScan, стало IndexSeek + KeyLookup. Второй остался прежним. По скорости практически идентичны. Спасибо всем, кто отвлёкся на мой вопрос. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.06.2021, 17:12 |
|
|
start [/forum/topic.php?fid=46&fpage=22&tid=1684614]: |
0ms |
get settings: |
8ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
38ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
52ms |
get tp. blocked users: |
2ms |
others: | 13ms |
total: | 148ms |
0 / 0 |