|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
На каждой таблице некластерные индексы по полю processed: Код: sql 1. 2. 3. 4.
Есть вьюха: Код: sql 1. 2. 3. 4. 5.
Так вот, когда мы пишем запрос: Код: sql 1. 2.
План запроса строиться по индексу idx_cur_processed (или idx_old_processed соответственно). А когда мы пишем так: Код: sql 1.
Происходит clustered index scan. Как мне добиться того, чтобы для этой вьюхи оптимизатор видел нужные индексы по полю processed? Код: sql 1. 2. 3. 4. 5.
... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2013, 18:23 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
Sorry, вьюха выглядит вот так: Код: sql 1. 2. 3. 4. 5. 6.
... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2013, 18:25 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
_ч_Как мне добиться того, чтобы для этой вьюхи оптимизатор видел нужные индексы по полю processed? И как по каждому индексу оптимизатор выберет _общие_ top 10 ? ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2013, 18:31 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
Glory, у меня тоже возникли такие же сомнения. И что же теперь делать? Не использовать union all во вьюхе? ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2013, 18:34 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
_ч_А когда мы пишем так: Код: sql 1.
Происходит clustered index scan. Пишите вот так: Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
С такой вьюхой на таком запросе каши не сваришь... ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2013, 18:36 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
_ч_у меня тоже возникли такие же сомнения. И что же теперь делать? Не использовать union all во вьюхе? если допустимо изменение структуры, то можно данные хранить в одной таблице вместо двух, только надо будет добавить еще поле с признаком ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2013, 18:38 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
Гость333, дело в том, что там не только индекс по полю processed. И order by может быть по другим полям. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2013, 18:44 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
Shakill, т.е. принципиально невозможно сделать так, чтобы оптимизатор приминил к этой вьюхе два индекса для каждой из таблиц? Надо менять структуру? ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2013, 18:45 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
_ч_т.е. принципиально невозможно сделать так, чтобы оптимизатор приминил к этой вьюхе два индекса для каждой из таблиц? Каким образом, если серверу все равно придется упорядочить общий набор записей ? ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2013, 18:47 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
Glory_ч_т.е. принципиально невозможно сделать так, чтобы оптимизатор приминил к этой вьюхе два индекса для каждой из таблиц? Каким образом, если серверу все равно придется упорядочить общий набор записей ?Ну в принципе оптимизатор мог бы использовать 2 индекса так же, как использовал Гость333. Но он так не делает, не заложен такой вариант... _ч_Надо менять структуру?Как я понимаю, эта структура сделана для ускорения работы сервера, типа душевная идея разделить базу на оперативную и архивную? Это очередная иллюстрация того, что такое разделение в лучшем случае не делает хуже :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
12.04.2013, 20:07 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
Glory, Вы как всегда правы. Значит ситуация очень плохая, т.к. индексы на представления с UNION ALL тоже не повесишь. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.04.2013, 10:08 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
_ч_, Оптимизатор может использовать два некластерных индекса из двух таблиц. Например, мог бы получиться вот такой план: По каждому некластерному индексу выполняется упорядоченный просмотр, после чего merge и ограничение топ. В чем вопрос, не понял. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.04.2013, 16:32 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
SomewhereSomehowОптимизатор может использовать два некластерных индекса из двух таблиц. Например, мог бы получиться вот такой план: Имхо Для этого нужно очень точно проводить оценку данных. Может оказаться, что ТОР превышает число записей в обеих таблицах ... |
|||
:
Нравится:
Не нравится:
|
|||
15.04.2013, 16:41 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
SomewhereSomehow, Вопрос в том, что выбирается вот такой вот план: |--Top(TOP EXPRESSION:((50))) |--Merge Join(Concatenation) |--Sort(ORDER BY:([cq].[processed] ASC, [cq].[bonus] ASC, [cq].[Id] ASC)) | |--Clustered Index Scan(OBJECT:([_old].[pk_old] AS [cq])) |--Sort(ORDER BY:([cq].[processed] ASC, [cq].[bonus] ASC, [cq].[Id] ASC)) |--Clustered Index Scan(OBJECT:([_cur].[pk_cur] AS [cq])) Вместо Вашего. Если бы был выбран Ваш, было бы всё в порядке. Т.е. проиходит сканирование по кластерным индексам pk_cur и pk_old, вместо более быстрого решения (сканирование по некластерным индексам idx_cur_processed и idx_old_processed). ... |
|||
:
Нравится:
Не нравится:
|
|||
15.04.2013, 17:39 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
Glory, Безусловно. Точная оценка всегда важна. _ч_, Судя по форме плана, есть подозрение, что те скрипты, которые вы привели могут отличаться от реальных. В тех что вы приведены у вас: - Два поля в таблице - ID - ключ кластерного индекса. - processed - ключ некластерного (в который включен кластерный по-умолчанию) Когда вы делаете "select *" - оптимизатору все равно из какого индекса выбирать, чтобы избежать Lookup (все поля есть во всех индексах), но не все равно какой выбирать из-за порядка сортировки. По этому, выбирается тот, что который может гарантировать сортировку при сканировании, в данном случае idx_XXX_processed. Но если условия не соблюдаются, например, какой-то из индексов, не содержит все поля, то оптимизатор может выбирать из следующих вариантов: 1. Сканировать кластерный (который содержит все поля), потом отсортировать (дорогая операция) 2. Избежать сортировки сканировав некластерный индекс, но в нужном порядке, и уже потом сделать Lookup из кластерного для недостающих полей (очень дорогая операция) Плюс добавить в уравнение то, что оптимизатор основывается на статистике, которая не всегда актуальна. Может быть он выбирает первый вариант, как менее затратный? Lookup очень дорого. Попробуйте, ради эксперимента поиграть с числом в TOP, например TOP(1) или TOP(2) тоже выберет план со сканом кластерного? Если да, то, наверное, без анализа планов не обойтись. Публикуйте сюда планы в виде xml, будем смотреть на оценки, о чем говорил Glory. Если же, при малом числе строк выбирается nonclustered index scan + key lookup, но как только число строк возрастает план скатывается в скан кластерного индекса - значит дело в этом. В таком случае, необходимо индекс делать покрывающим (т.е. добавить в него все поля которые участвуют в запросе). Вот какие планы были бы возможны. Подготовка: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
Запросы: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9.
Планы: Можно сделать покрывающие индексы и повторить запросы: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
Планы: П.С. Если вам это не поможет, то выкладывайте сюда планы (только не картинками как я, т.к. в моем случае, реальные планы могут воспроизвести любые желающие, запустив скрипты, а свои реальные планы в формате xml, реальные еще и в том смысле, что не estimated (оценочные), а actual (реальные или актуальные), чтобы можно было сравнить оценки и действительность). ... |
|||
:
Нравится:
Не нравится:
|
|||
15.04.2013, 19:31 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
SomewhereSomehow, Спасибо за заинтересованность, всё оказалось довольно запутанее. Вот скрипт на создание таблиц и заполнение (заполняется только одна): Код: 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.
А теперь я запускаю три простых запроса (с top 50 как и на боевой базе): Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9.
... |
|||
:
Нравится:
Не нравится:
|
|||
16.04.2013, 10:00 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
SomewhereSomehowGlory, Безусловно. Точная оценка всегда важна. На мой взгляд, это уже больше похоже на секционирование. Которое и так уже есть. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.04.2013, 10:02 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
Так вот, из плана хорошо видно, что в случае запроса Код: sql 1. 2.
Оптимизатор сканирует некластерный индекс, а в случае: Код: sql 1. 2.
сканирует уже кластерный. Если поменять в некластерном индексе сортировку, то ситуация повториться с точностью до наоборот. Если же сделать два некластерных индекса по полю procressed с сортировкой asc и desc, то план запроса строиться на сканировании только этих некластерных индексов. Всё это происходит на двух серверах 2012. Код: sql 1. 2. 3. 4. 5.
Сейчас буду ставить SP1 и тестировать там эту особенность поведения оптимизатора. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.04.2013, 10:07 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
А не желаете в некластерный индекс добавить в виде include полей summ и name, чтобы не тратить ресурсы на операцию key lookup ? ... |
|||
:
Нравится:
Не нравится:
|
|||
16.04.2013, 10:48 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
Мистер Хенки, В данном случае меня интересует вопрос как так получилось, что порядок сортировки в индексе и запросе влияет на выбор оптимизатора. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.04.2013, 10:53 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
_ч_Мистер Хенки, В данном случае меня интересует вопрос как так получилось, что порядок сортировки в индексе и запросе влияет на выбор оптимизатора. потому что merge выдаст поток данных отсортированный в desc порядке(порядок у индексов) и надо будет еще его сортировать, чтобы сделать order by asc- как то так видимо. Если создадите покрывающие индексы, то увидете, что оптимизатор выберет их использование, но все равно будет сортировать перед merge join ... |
|||
:
Нравится:
Не нравится:
|
|||
16.04.2013, 11:22 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
Мистер Хенки, воспользовался Вашим советом. Теперь планы выглядят так: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
Уже лучше, за тем исключением, что первый запрос отрабатывает 15 секунд, а второй доли секунд. А еще огромный минус в том, что полей в реальной таблице, а не тестовой гораздо больше. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.04.2013, 11:37 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
План картинкой, кому лень скачивать xml. Теперь версия сервера авторMicrosoft SQL Server 2012 (SP1) - 11.0.3000.0 (X64) Oct 19 2012 13:38:57 Copyright (c) Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) ... |
|||
:
Нравится:
Не нравится:
|
|||
16.04.2013, 11:40 |
|
В представлении оптимизатор не видит индексов
|
|||
---|---|---|---|
#18+
_ч_Мистер Хенки, воспользовался Вашим советом. Уже лучше, за тем исключением, что первый запрос отрабатывает 15 секунд, а второй доли секунд. А еще огромный минус в том, что полей в реальной таблице, а не тестовой гораздо больше. Тогда возвращайтесь к первоначальному варианту и указывайте кластерный ключ явно при сортировке Код: sql 1. 2. 3. 4. 5.
... |
|||
:
Нравится:
Не нравится:
|
|||
16.04.2013, 12:16 |
|
|
start [/forum/topic.php?fid=46&msg=38223973&tid=1707357]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
35ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
59ms |
get tp. blocked users: |
1ms |
others: | 239ms |
total: | 379ms |
0 / 0 |