Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
Возникла некоторая странность, есть таблица с индексом Код: sql 1. 2. Далее делается простой селект Код: sql 1. Так вот если указать в скобках количество значений меньше 64, то запрос отрабатывает исключительно по index seek, но вот если указать количество значений большее, то план запроса меняется на index scan + filter, и естественно весь список этих значений попадает в фильтр и индекс по сути не работает. Пробовал чинить всякими хинтами, но ничерта не помогло, единственный способ который помог, это добавить еще одно условие в запрос Код: sql 1. Данное условие никак не влияет на результат выборки, но меняет план на использование index seek. Проблема заключается в том, что нет простой возможности напихать везде подобные "спасительные" условия, а хочется понять, что за магия происходит и как этим бороться вменяемыми способами. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2019, 18:37 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
fallenyashaно вот если указать количество значений большее, то план запроса меняется на index scan + filter, В какой-то момент скан становится вогоднее кучи seek, это нормально. Ну или тут какие-то правила оптимизации in с константами. fallenyashaПробовал чинить всякими хинтами, но ничерта не помогло, единственный способ который помог, это добавить еще одно условие в запросДля этого давно сделали хинт with ( forceseek ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2019, 18:40 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
В том то и дело, что forceseek ничего не дал, кроме усложнения плана, происходит index scan + join. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2019, 18:51 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
Так же можно использовать перечисление вида a=1 or a=2 or ..., это никак не влияет на план. Сие точно надо как-то исправлять, т.к. скан на 1000 записей на реальной таблице работает больше 10 секунд, а сик меньше секунды, так что скан ну уж точно не выгоднее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2019, 18:54 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
fallenyasha, переделайте в джоин ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2019, 19:02 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
fallenyashaТак вот если указать в скобках количество значений меньше 64 Снова 64 элемента и отказ оптимизатора от оптимизации... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2019, 19:48 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
Посетительfallenyasha, переделайте в джоинДжойн с табличной переменной. Тогда точно будет seek. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2019, 22:42 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
К сожалению это невыполнимо, запросы формируются Entity Framework и это легаси-код, и по сути все на что можно повлиять это индексы, настройки БД, возможно какие-то параметры подключения, может что еще по мелочевке, но переписывать код, заменяя EF на прямые запросы вообще не вариант :( Поэтому и стоит задача, понять откуда растет эта проблема и как ее можно решить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2019, 23:19 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
fallenyashaзапросы формируются Entity FrameworkА, понятно, архитектурная ошибка :-( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2019, 23:20 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
fallenyashaПоэтому и стоит задача, понять откуда растет эта проблема и как ее можно решить.Из Entity Framework, очевидно же. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2019, 23:25 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
Гавриленко Сергей АлексеевичfallenyashaПоэтому и стоит задача, понять откуда растет эта проблема и как ее можно решить.Из Entity Framework, очевидно же.Добавлю для fallenyasha, что печально не только использование Entity Framework, но и то, для чего его используют. А именно, цель горе-менеджеров и горе-архитекторов - достичь 2 фантастически полезных результата: 1) в проекте не нужно иметь ни одного специалиста по БД (что сразу видно по планам запросов), 2) при проблемах не надо звать DBA, ведь можно всё легко и просто поправить в C# коде (хихи). Итого, модель данных и их потоков безумная, планы запросов можно распечатывать на всю стену, и поправить это можно только каким то шаманством, тыкать в статистики и индексы, авось что то поможет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2019, 23:46 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
Предлагаете заняться оптимизацией EF? :) По сути EF всего лишь формирует запрос, который я описал в начале, т.е. просто селект записей из таблицы по определенному условию, где условием является набор неких идентификаторов например. А тупит именно SQL, что неправильно формирует план по непонятной причине, задача сводится к тому, как ему объяснить что он не прав, бишь как реально принудительно включить seek. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.04.2019, 23:47 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
fallenyashaПредлагаете заняться оптимизацией EF? :) По сути EF всего лишь формирует запрос, который я описал в начале, т.е. просто селект записей из таблицы по определенному условию, где условием является набор неких идентификаторов например. А тупит именно SQL, что неправильно формирует план по непонятной причине, задача сводится к тому, как ему объяснить что он не прав, бишь как реально принудительно включить seek.Задайте это вопрос создателям EF, зачем они таким образом делают запросы. Сделать seek по списку значений в MSSQL есть вагон и маленькая тележка способов, главное, видимо, in не использовать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2019, 00:07 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
Реальный запрос выглядит так: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. IN я использовал просто для краткости, а вообще его использование никак не влияет на результат. Закоментарен костыль, включающий seek и ускоряющий работу этой шайтан-машины более чем в 10 раз. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2019, 00:15 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
fallenyasha, Так в чем странность? Это ожидаемое поведение ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2019, 08:11 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
fallenyashaК сожалению это невыполнимо, запросы формируются Entity Framework и это легаси-код, и по сути все на что можно повлиять это индексы, настройки БД, возможно какие-то параметры подключения, может что еще по мелочевке, но переписывать код, заменяя EF на прямые запросы вообще не вариант :( Поэтому и стоит задача, понять откуда растет эта проблема и как ее можно решить. Никак её не решит Тебе надо перейти от синтетического примера к решению проблем производительности твоих конкретных запросов, разные запросы по-разному оптимизируется. И структуры у тебя не такие, и данные не такие... Ты не можешь починить один запрос решая проблема производительности другого запроса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2019, 08:16 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
Товарищи, забудьте про EF, забудьте про разность запросов, это все и так понятно, сейчас решил эту задачу через сей костыль, все нормально работает для разных таблиц, полей и т.д. Осталась непонятна логика SQL, на основании каких критериев принимается решение об использовании seek или scan, хочется докопаться до истины и понять нутро и методы воздействия на него, чтобы в будущем более осмысленно писать запросы, а не методом перебора планов и костылей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2019, 09:32 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
fallenyashaОсталась непонятна логика SQL, на основании каких критериев принимается решение об использовании seek или scan, хочется докопаться до истины и понять нутро и методы воздействия на него, чтобы в будущем более осмысленно писать запросы, а не методом перебора планов и костылей.По статистике или, возможно, по каким-то правилам оптимизации. Зависит от запроса. Вы про какой именно сейчас? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2019, 10:07 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
Скорее всего это некое правило оптимизации, т.к. ограничение на 64 значения срабатывает для любых таблиц и полей ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2019, 10:15 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
fallenyashaРеальный запрос выглядит так: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. IN я использовал просто для краткости, а вообще его использование никак не влияет на результат. Закоментарен костыль, включающий seek и ускоряющий работу этой шайтан-машины более чем в 10 раз. А мужики то и не знают!!! ЗЫ. Это в цирке надо показывать Код: sql 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2019, 10:23 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
fallenyashaСкорее всего это некое правило оптимизации, т.к. ограничение на 64 значения срабатывает для любых таблиц и полей Есть два магических числа 16 и 64, с которыми связана работа оптимизатора с предикатами в SQL Server. <16 - число для nonSARGable предикатов, которые могут быть продвинуты на уровень сканирования, если 16 и более - условие выносится в отдельный оператор фильтра. <= 64 - число sargable предикатов, которые могут быть продвинуты на уровень одиночной операции поиска, если более 64, то они выносятся в отдельный оператор Constant Scan (некая внутренняя "таблица" в памяти), который соединяется при помощи NL с вашей таблицей, но от этого Seek не перестает быть Seek-ом. Это не документировано, или можно сказать, полудокументировано, читайте блог одного из разработчиков оптимизатора Conor Cuningham: https://www.sqlskills.com/blogs/conor/interesting/ Чтобы точно ответить на ваш вопрос, нужен репро-скрипт, либо, хотя бы, структура таблицы и индексов + действительные планы запроса Seek для 64 и Scan для 65, в формате .sqlplan, приложенные к сообщению. Пока могу предположить, что у вас происходит вот так: Код: 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. Так получается, потому, что Merge Concatenation тоже имеет свой предел, именно в 64. Можете попробовать: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. Раскомментируете последнюю строку и получите ошибку: Query processor could not produce a query plan because of the hints defined in this query. Resubmit the query without specifying any hints and without using SET FORCEPLAN. Получается: 1) вариант с одиночным поиском и 65 условий вынести в отдельный ConstantScan нельзя, т.к. туда выносятся только SARGable предикаты, а видимо не все такие. 2) вариант разбирать на несколько одиночных поисков в одном операторе нельзя по той же причине 3) вариант разбирать на несколько условий поиска в каждом из которых проверять и SARGable и nonSARGable (residual), а потом соединять их Merge Join - упирается в ограничение 64 операции Merge Join. Остается два варианта у оптимизатора: 4) соединять каждый отдельный поиск при помощи Concatenation и уже после этого исключить дубли (это то, что у меня происходит, если выполнить запрос с FORCESEEK, странно, что у вас не сработало, может все-таки, что-то другое у вас, планов то так и нет) 5) выполнить сканирование и фильтрацию. Если у вас ситуация схожая с моим примером, то попробуйте добавить все поля таблицы условия where, в индекс, это сделает их все предикатами поиска и оптимизатор сможет использовать вариант 2. Резюмируя, могу сказать, что не забудьте проверить вариант 2, на числа 128, 256, 512, 1024 и т.д. =) Мало ли магических чисел в SQL Server. Если серьезно, то на мой взгляд нужно что-то править в архитектуре или подходе, согласен с alexeyvg. Может сейчас вам поможет этот или другой совет, но в следующий раз что, опять на форум идти? Одна из хороших практик работы с реляционной БД - be relational. Удачи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.04.2019, 12:25 |
|
||
|
Использование индексов
|
|||
|---|---|---|---|
|
#18+
SomewhereSomehow, спасибо за развернутый ответ, многое стало понятно. Про исправление архитектуры или подхода все как обычно, проект достался в наследство, сроки горят, дедлайны прошли еще в прошом веке, так что приходится страдать :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.04.2019, 10:42 |
|
||
|
|

start [/forum/topic.php?fid=46&gotonew=1&tid=1687896]: |
0ms |
get settings: |
8ms |
get forum list: |
10ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
33ms |
get topic data: |
11ms |
get first new msg: |
4ms |
get forum data: |
2ms |
get page messages: |
51ms |
get tp. blocked users: |
5ms |
| others: | 261ms |
| total: | 389ms |

| 0 / 0 |
