Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Кривой план запроса SQL. Можно ли исправить? / 25 сообщений из 29, страница 1 из 2
24.05.2021, 16:29
    #40072503
WPuh
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
Добрый денечек! Сам я 1С-ник, но SQL приходится пользовать частенько. Столкнулся с неоптимальным выполнением запроса скулем. Суть запроса: в 1С 7.7 надо выбрать подчиненные документы определенного вида. И родился такой запрос:
Код: 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.
SELECT
   Доки.IDDOC as [Док $Документ],
   Доки.Проведен as Проведен,
   Доки.ISMARK as ПометкаУдаления,
	Доки.Док_вид as [ВидДок $ВидДокумента],
	Доки.Док_вид as Док_вид
From
(SELECT
   Жур.IDDOC,
   Жур.Closed&1 as Проведен,
   Жур.ISMARK,
   Жур.IDDOCDEF as ВидДок,
	Жур.IDDOCDEF Док_вид,
	Отбор.CHILD_DATE_TIME_IDDOC
FROM
 _1SCRDOC as Отбор (NOLOCK)
INNER JOIN
 _1SJOURN As Жур (NOLOCK) ON Отбор.ChildID = Жур.IDDOC
WHERE
 (Отбор.ParentVal='O1 2CM ZNTCE           ') AND (Отбор.MDID=0) 
) Доки

WHERE   (Доки.Док_вид=49116) AND (Доки.ISMARK=0)
Order by
 Доки.CHILD_DATE_TIME_IDDOC



Вообще родился он не совсем в таком виде - был изначально один Select. Но когда выяснилось, что условие Док_вид=49116 сильно влияет на скорость, запрос превратился в такой. Суть проблемы: если Док_вид=49116 запрос выполняется 1000 мсек, если Док_вид=49117, то запрос выполняется 15 мсек. Получается запрос судя по плану запросов пытается наложить фильтр на поле IDDOCDEF таблицы _1SJOURN. Индексов подходящих по нему нет.
Но почему он накладывает этот фильтр, если условие находится во внешнем селекте, разве внутренний селект не должен отработать самостоятельно, а потом сработать внешний по результатам внутреннего? Внутренний селект выдает не более 10 строк и внешнему для фильтрации по полю IDDOCDEF (Док_вид) индексы вообще не нужны были бы.
...
Рейтинг: 0 / 0
24.05.2021, 16:54
    #40072516
0wl
0wl
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
WPuh,

вложенные запросы разворачиваются в единый план выполнения вместе с основным запросом (но вы и так это должны были видеть в плане). Так что никакой гарантии порядка выполнения нет - операции будут выполняться так, как СУБД посчитает нужным.

Приложите планы (и быстрый, и медленный) - так понятнее будет, за что бороться
...
Рейтинг: 0 / 0
24.05.2021, 17:15
    #40072525
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
WPuh,

Планы нужно показывать, а не пересказывать. Желательно актуальные и в формате 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.
SELECT
   Доки.IDDOC as [Док $Документ],
   Доки.Проведен as Проведен,
   Доки.ISMARK as ПометкаУдаления,
	Доки.Док_вид as [ВидДок $ВидДокумента],
	Доки.Док_вид as Док_вид
From
(SELECT top (1000000)
   Жур.IDDOC,
   Жур.Closed&1 as Проведен,
   Жур.ISMARK,
   Жур.IDDOCDEF as ВидДок,
	Жур.IDDOCDEF Док_вид,
	Отбор.CHILD_DATE_TIME_IDDOC
FROM
 _1SCRDOC as Отбор (NOLOCK)
INNER JOIN
 _1SJOURN As Жур (NOLOCK) ON Отбор.ChildID = Жур.IDDOC
WHERE
 (Отбор.ParentVal='O1 2CM ZNTCE           ') AND (Отбор.MDID=0) 
) Доки

WHERE   (Доки.Док_вид=49116) AND (Доки.ISMARK=0)
Order by
 Доки.CHILD_DATE_TIME_IDDOC
...
Рейтинг: 0 / 0
24.05.2021, 17:21
    #40072529
WPuh
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
0wl,

спасибо. Предполагал, что такой ответ может быть. Очень жаль - хотелось все фильтры в запросе наложить. Теперь придется накладывать на стороне клиента, либо внутренний селект помещать в отдельную таблицу и далее выбирать из нее. Планы запросов медленный и быстрый ничем не отличаются - сравнил два xml файла запросов.
...
Рейтинг: 0 / 0
24.05.2021, 17:26
    #40072531
WPuh
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
invm,

суперское решение. Помогло!! Спасибо огромное! Про такую фичу я не знал. Можно считать вопрос закрытым.
...
Рейтинг: 0 / 0
24.05.2021, 18:15
    #40072547
Кесарь
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
WPuh,

только это костыль.


Будьте проще. Проще код, проще отлаживать. Проще код, оптимизатору проще выбрать оптимальный план.

Создайте временную таблицу или табличную переменную. В неё записывайте предварительную инфу, которая начитывается внутренним запросом. Затем уже из этой временной таблицы/переменной читайте то, что нужно основным селектом.


* Если промежуточных данных много (десятки тысяч записей и более), то создавайте временную таблицу. Если наоборот мало (не более нескольких тысяч), то делайте через переменную.

** Так же можно в зависимости от кол-ва данных поэкспериментировать с индексами по искомым полям.


Такое решение позволит оптимизировать каждый запрос по шагам и будет более стабильно.
...
Рейтинг: 0 / 0
24.05.2021, 18:30
    #40072551
WPuh
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
Кесарь,

спасибо за подсказку про табличную переменную! Не знал о таком покопаю в эту сторону.
...
Рейтинг: 0 / 0
24.05.2021, 19:39
    #40072567
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
Кесарь
Создайте временную таблицу или табличную переменную.
Зачем?
В данном конкретном случае они не нужны. Совсем. Будет просто лишняя трата ресурсов.
...
Рейтинг: 0 / 0
24.05.2021, 19:52
    #40072568
Кесарь
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
invm
Кесарь
Создайте временную таблицу или табличную переменную.
Зачем?
В данном конкретном случае они не нужны. Совсем. Будет просто лишняя трата ресурсов.


На слабо нагруженном сервере это не так важно. А на высоко нагруженном, как показывает практика, разделение на отдельные блоки даёт стабильность и управляемость. Потому что оптимизатор успевает строить правильные планы.

И без костылей.
...
Рейтинг: 0 / 0
24.05.2021, 20:29
    #40072570
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
Кесарь
И без костылей.
И где тут костыли?
...
Рейтинг: 0 / 0
24.05.2021, 21:39
    #40072576
DaniilSeryi
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
invm
Кесарь
И без костылей.
И где тут костыли?


Код: sql
1.
top (1000000)

, я думаю. Если число записей, которые должен вернуть запрос, больше миллиона, то нехорошо получится.
...
Рейтинг: 0 / 0
24.05.2021, 21:45
    #40072577
Гавриленко Сергей Алексеевич
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
Ну top (9223372036854775807) напишите, столько точно не вернет.
...
Рейтинг: 0 / 0
24.05.2021, 21:47
    #40072578
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
DaniilSeryi
я думаю. Если число записей, которые должен вернуть запрос, больше миллиона, то нехорошо получится.
WPuh
Внутренний селект выдает не более 10 строк
...
Рейтинг: 0 / 0
24.05.2021, 21:55
    #40072580
DaniilSeryi
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
WPuh,

Пачка вопросов.
1. А покрывающие индексы нельзя создать принципиально?
2. Поле
Код: sql
1.
Жур.IDDOCDEF as ВидДок

в подзапросе принципиально не используется во внешнем запросе?
3. Смысл дублировать поле
Код: sql
1.
Жур.IDDOCDEF Док_вид,	


во внешнем запросе?
Код: sql
1.
2.
	Доки.Док_вид as [ВидДок $ВидДокумента],
	Доки.Док_вид as Док_вид



4. А если убрать внешний и внутренний подзапросы и объединить в один?
...
Рейтинг: 0 / 0
25.05.2021, 09:45
    #40072618
WPuh
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
DaniilSeryi,

автор1. А покрывающие индексы нельзя создать принципиально?
На мой взгляд в данной ситуации это костыль для решение проблемы неоптимального плана запроса.
автор4. А если убрать внешний и внутренний подзапросы и объединить в один?
тогда точно без индекса не обойтись. А так Top 1000 решает проблему при использовании вложенного запроса.
...
Рейтинг: 0 / 0
25.05.2021, 09:53
    #40072620
Oleg_SQL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
WPuh,

На днях аналогичная проблема была при запросе на ~3 млн строк (для куба).

SELECT TOP 1 000 000 - работал мгновенно
SELECT TOP 5 000 000 - вешал намертво, с запасом...


Пришлось накостылять серверу Join Hints (LOOP | HASH | MERGE | REMOTE)
...
Рейтинг: 0 / 0
25.05.2021, 10:49
    #40072640
DaniilSeryi
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
WPuh
DaniilSeryi,

автор1. А покрывающие индексы нельзя создать принципиально?

На мой взгляд в данной ситуации это костыль для решение проблемы неоптимального плана запроса.
автор4. А если убрать внешний и внутренний подзапросы и объединить в один?
тогда точно без индекса не обойтись. А так Top 1000 решает проблему при использовании вложенного запроса.

Открою Вам страшную тайну - это не костыль, а основное средство ускорения запросов.
...
Рейтинг: 0 / 0
25.05.2021, 11:58
    #40072682
Владислав Колосов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
DaniilSeryi,

костыль - это всё, что является эксплойтом системы. top (1М) - это очевидный эксплойт.
...
Рейтинг: 0 / 0
25.05.2021, 14:55
    #40072747
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
Владислав Колосов
top (1М) - это очевидный эксплойт.
Да? И в чем же эксплойтность?

Сторонникам "костыльности" стоило бы разобраться для чего и почему применено предложение top(), а потом уже выносить суждение.
А применено оно для устранения проблемы ТС, а именно проталкивания вниз предиката (Доки.Док_вид=49116) AND (Доки.ISMARK=0)
100000 - для предотвращения искажения плана из-за row goal
...
Рейтинг: 0 / 0
25.05.2021, 16:43
    #40072798
Кесарь
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
invm,

а мы не говорим, что это не решает проблему. Решает. Но это костыль.




Там ещё кстати вызывает вопросы nolock. Чем продиктовано использование подсказки? Это реальное свойство бизнес-процесса или очередной костыль, чтобы хоть как-то работало?
...
Рейтинг: 0 / 0
25.05.2021, 16:51
    #40072803
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
Кесарь
Но это костыль.
Ну да.
Только никто не может внятно объяснить почему.
Уже и до эксплойтов дошли...
...
Рейтинг: 0 / 0
25.05.2021, 16:57
    #40072807
Кесарь
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
invm
Кесарь
Но это костыль.
Ну да.
Только никто не может внятно объяснить почему.
Уже и до эксплойтов дошли...


Да потому что любые точные указания там, где возможны варианты, это костыль.

В одним местах в ходу условия по доменным учёткам сотрудников прямо в коде (да-да, именно так), в других хинты, в третьих вот топ миллион. И все полагают, что у них всё норм и так и надо.

Но это всё костыли (и гвозди, по учёткам - это конкретно гвозди, а хинты и топ-миллионы - это костыли).
...
Рейтинг: 0 / 0
25.05.2021, 17:32
    #40072822
Владислав Колосов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
invm,

разумеется эксплойт, поскольку это манипуляция с механизмом формирования плана. Я не пишу, что это плохо, сам механизм самостоятельно решение, подобное результату с top() не принял, а мы достигли желаемого результата.
Поведение это не инвариантно, оно зависит от типа и версии SQL сервера. Не думаю, что на MySQL подобный трюк сработал бы.
...
Рейтинг: 0 / 0
25.05.2021, 17:34
    #40072823
Владислав Колосов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
Кесарь,

вот насчет хинтов не соглашусь, поскольку это документированное средство воздействия на план запроса.
...
Рейтинг: 0 / 0
25.05.2021, 17:45
    #40072829
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Кривой план запроса SQL. Можно ли исправить?
Кесарь
Да потому что любые точные указания там, где возможны варианты, это костыль.
Почитайте определение термина "костыль".

Если следовать вешей же логике, то предложение воспользоваться табличной переменной (временной таблицей) - такой же костыль.
И, например, любые средства фиксации плана выполнения - костыль.
Потому что все перечисленное относится к "точные указания там, где возможны варианты".
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Кривой план запроса SQL. Можно ли исправить? / 25 сообщений из 29, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]