Я вижу, что вы отправили the plans. Просто удача вничью.
Ваш фактический запрос состоит из 16 табличных соединений.
SELECT max(atDate1) AS AtDate1,
min(atDate2) AS AtDate2,
max(vtDate1) AS vtDate1,
min(vtDate2) AS vtDate2,
max(bgtDate1) AS bgtDate1,
min(bgtDate2) AS bgtDate2,
max(lftDate1) AS lftDate1,
min(lftDate2) AS lftDate2,
max(lgtDate1) AS lgtDate1,
min(lgtDate2) AS lgtDate2,
max(bltDate1) AS bltDate1,
min(bltDate2) AS bltDate2
FROM (SELECT TOP 100000 at.Date1 AS atDate1,
at.Date2 AS atDate2,
vt.Date1 AS vtDate1,
vt.Date2 AS vtDate2,
bgt.Date1 AS bgtDate1,
bgt.Date2 AS bgtDate2,
lft.Date1 AS lftDate1,
lft.Date2 AS lftDate2,
lgt.Date1 AS lgtDate1,
lgt.Date2 AS lgtDate2,
blt.Date1 AS bltDate1,
blt.Date2 AS bltDate2
FROM dbo.Tab1 a
INNER JOIN dbo.Tab2 at
ON a.id = at.Tab1Id
AND cast(Getdate() AS DATE) BETWEEN at.Date1 AND at.Date2
INNER JOIN dbo.Tab5 v
ON v.Tab1Id = a.Id
INNER JOIN dbo.Tab16 g
ON g.Tab5Id = v.Id
INNER JOIN dbo.Tab3 vt
ON v.id = vt.Tab5Id
AND cast(Getdate() AS DATE) BETWEEN vt.Date1 AND vt.Date2
LEFT OUTER JOIN dbo.Tab4 vk
ON v.id = vk.Tab5Id
LEFT OUTER JOIN dbo.VerkaufsTab3 vkt
ON vk.id = vkt.Tab4Id
LEFT OUTER JOIN dbo.Plu p
ON p.Tab4Id = vk.Id
LEFT OUTER JOIN dbo.Tab15 bg
ON bg.Tab5Id = v.Id
LEFT OUTER JOIN dbo.Tab7 bgt
ON bgt.Tab15Id = bg.Id
AND cast(Getdate() AS DATE) BETWEEN bgt.Date1 AND bgt.Date2
LEFT OUTER JOIN dbo.Tab11 b
ON b.Tab15Id = bg.Id
LEFT OUTER JOIN dbo.Tab14 lf
ON lf.Id = b.Id
LEFT OUTER JOIN dbo.Tab8 lft
ON lft.Tab14Id = lf.Id
AND cast(Getdate() AS DATE) BETWEEN lft.Date1 AND lft.Date2
LEFT OUTER JOIN dbo.Tab13 lg
ON lg.Id = b.Id
LEFT OUTER JOIN dbo.Tab9 lgt
ON lgt.Tab13Id = lg.Id
AND cast(Getdate() AS DATE) BETWEEN lgt.Date1 AND lgt.Date2
LEFT OUTER JOIN dbo.Tab10 bl
ON bl.Tab11Id = b.Id
LEFT OUTER JOIN dbo.Tab6 blt
ON blt.Tab10Id = bl.Id
AND cast(Getdate() AS DATE) BETWEEN blt.Date1 AND blt.Date2
WHERE a.Nummer = 223889) B
На обоих хорошие и плохие планы План выполнения показывает «Причина досрочного прекращения Statement оптимизации», как «Time Out».
В двух планах несколько разных заказов на соединение.
Единственное соединение в планах, которые не удовлетворены поиском индекса, это то, что на Tab9
. Это 63 926 строк.
Отсутствующие данные индекса в плане выполнения предлагают создать следующий индекс.
CREATE NONCLUSTERED INDEX [miising_index]
ON [dbo].[Tab9] ([Date1],[Date2])
INCLUDE ([Tab13Id])
Проблемная часть плохого плана может быть четко видна в SQL Sentry Plan Explorer, оценки
SQL Server, который 1.349174 строки будет возвращена из предыдущего присоединяется вступления в объединении на Tab9
. И, следовательно, затраты на вложенные петли соединяются так, как если бы ему нужно было выполнить сканирование на внутренней таблице 1.349174 раза.
Фактически в это соединение входит 2600 строк, что означает, что оно составляет 2600 полных сканирований Tab9
(2,600 * 63,926 = 164,569,600 строк.)
Как раз так получается, что по хорошему плану предполагаемое количество строк, входящих в соединение, равно 2.74319. Это все еще неверно на три порядка, но немного увеличенная оценка означает, что SQL Server предпочитает хеш-соединение. Хэш присоединиться только делает один проход через Tab9
Я бы первый попробовать добавить отсутствующий индекс на Tab9
.
Также/вместо этого вы можете попробовать обновить статистику по всем таблицам, участвующих (особенно с даты предиката, таких как Tab2
Tab3
Tab7
Tab8
Tab6
) и посмотреть, если это идет некоторый путь к исправлению огромное расхождение между предполагаемыми и фактическими рядами на слева от плана.
Также может помочь разбить запрос на более мелкие части и материализовать их во временные таблицы с соответствующими индексами. Затем SQL Server может использовать статистику по этим частичным результатам для принятия более эффективных решений о присоединениях позже в плане.
Только в качестве последнего средства я бы рассмотрел использование подсказок для запроса, чтобы попытаться заставить план с хеш-соединением. Ваши варианты для этого - либо подсказка USE PLAN
, в этом случае вы определяете именно тот план, который вы хотите, включая все типы и заказы на объединение, или указав LEFT OUTER HASH JOIN tab9 ...
. Этот второй вариант также имеет побочный эффект от фиксации всех заказов на соединение в плане. Оба означают, что SQL Server будет сильно ограничен, так это его способность корректировать план с изменениями в распределении данных.
Чтобы убедиться, вам нужно взглянуть на план выполнения. Вероятно, он использует более эффективный путь с TOP, чем без него. – Khan
Это может быть вызвано проблемой оптимизатора. Можете ли вы предоставить планы выполнения для обоих запросов? –
Лучший способ предоставления планов выполнения - запустить их в SSMS с включенным опцией «Query -> Include Actual Execution Plan», а затем загрузить версию XML до сайта, такого как pastebin. См. [Как предоставить план выполнения кому-либо для анализа?] (Http://meta.dba.stackexchange.com/questions/796/how-do-i-provide-an-execution-plan-to-someone- для анализа) для большего. –