Мой план выполнения пытается обмануть меня?
Я пытаюсь ускорить выполнение длинного запроса (занимает около 10 минут...). Чтобы отследить, какая часть запроса стоит мне больше всего, я включил Фактический план выполнения, когда запустил его и нашел определенный раздел, который занимал 55% (снимок экрана ниже)
http://img109.imageshack.us/img109/9571/53218794.png
Мне это показалось не совсем правильным, поэтому я добавил Print '1'
а также Print '2'
до и после этой неприятности. Когда я запускаю запрос всего 17 секунд, а затем отменяю его, распечатывается 1 и 2, что, как я предполагаю, означает, что он проходит через этот раздел в первые 17 секунд.
http://img297.imageshack.us/img297/4739/66797633.png
Я здесь что-то делаю не так или мой план казни вводит меня в заблуждение?
4 ответа
Я бы не поверил, что печать '1' и '2' докажет что-нибудь о том, что выполнено, а что нет. Я делаю то же самое, но я бы не стал полагаться на это в качестве доказательства. Вы можете напечатать @@rowcount из этого первого запроса на вставку - это будет точно указывать, что вставка произошла.
Хотя в плане сказано, что запрос может занять 55% стоимости, он может не составлять 55% времени выполнения, особенно если результаты запроса кэшируются.
Еще одним преимуществом печати @@rowcount является сравнение фактического количества строк с приблизительными (51 КБ). Если они сильно различаются, вы можете изучить статистику по вашим индексам.
Метрики от perfmon также помогут выяснить, что происходит не так... вы можете столкнуться с серьезными проблемами ввода-вывода с диском, на котором находится база данных tempDB. Кроме того, запустите трассировку и посмотрите на CPU и IO фактического запуска.
Хорошие метрики производительности, на которые стоит обратить внимание, это длина очереди диска (в среднем и записи).
Если у вас нет доступа к perfmon или вы не хотите отслеживать вещи, используйте "SET STATISTICS IO ON" в начале вашего запроса и дайте ему завершиться... не останавливайте его. Тот факт, что план выполнения говорит о том, что он вступает во владение, не означает, что он будет выполняться в течение половины времени запроса... это может быть намного больше (или меньше).
Это говорит Query 10: Query cost (relative to the batch): 55%
, Являются ли 100% уверенными, что это 10-е утверждение в пакете, которое вы переполнили заявлениями Print? Может ли INSERT ... INTO #mpProgramSet2 выполняться несколько раз, иногда менее чем за 17 секунд, а другой - в течение 5 минут, в зависимости от того, сколько данных было выбрано / вставлено?
Как примечание вы должны работать с SET STATISTICS TIME ON
вместо того, чтобы печатать, это даст вам точное время компиляции / выполнения и время выполнения каждого оператора в пакете.
Нам нужен полный запрос, чтобы понять, что происходит; но я бы, вероятно, начал с установки MAXDOP в 1, чтобы ограничить число процессоров, на которых он работает.
Обратите внимание, что иногда запросы должны быть ограничены только одним процессором из-за блокировок и т. Д.
Кроме того, вы можете попробовать добавить NOLOCK в любой из ваших выборов, которые могут избежать грязного чтения.