Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 дополнительное поле в order by ускоряет выборку  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
есть вьюха. выборка последних 100 записей к указанной дате стабильно длится 2-3 секунды, если в order by дописываю ещё одно поле (любое, кроме hasFlag), то выборка происходит практически мгновенно

поясните доступно, что произошло
+ вьюха и запрос

CREATE VIEW dbo.MyView
AS
	SELECT sv.dt, CASE WHEN shf.dt IS NULL THEN 0 ELSE 1 END hasFlag, shf.paramT, shf.kodA, shf.kodB, shf.kodC
	FROM nsi.TableSV sv	
	LEFT JOIN (
		SELECT sh.dt, sh.paramT, sh.kodA, sh.kodB, sl.kodC 
		FROM BASE1.dbo.tableSH sh 
		JOIN BASE2.dbo.TableSL sl ON sh.kodA = sl.kodA AND sh.kodB = sl.kodB AND sl.Enable = 1		
		WHERE EXISTS( 
			SELECT *
			FROM ( 
				SELECT TOP 1 *
				FROM BASE1.dbo.tableSE se
				WHERE se.kodA = sl.kodA AND se.kodB = sl.kodB AND se.dt <= sh.dt
				ORDER BY se.dt DESC
			) r
			WHERE r.paramS = 1
			
		)
	) shf ON shf.dt = sv.dt
GO

SELECT TOP 100 * 
FROM dbo.MyView 
WHERE dt <= '20100525' 
ORDER BY dt DESC, kodA -- kodA int
+ планы
1. быстрый запрос (order by dt desc, kodA)

Table 'tableSE'. Scan count 305, logical reads 1098, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'TableSL'. Scan count 183, logical reads 366, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tableSH'. Scan count 61, logical reads 129, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'TableSV'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.


|--Compute Scalar(DEFINE:([Expr1015]=CASE WHEN [Expr1010] IS NULL THEN (0) ELSE (1) END))
|--Top(TOP EXPRESSION:((100)))
|--Nested Loops(Left Outer Join, OUTER REFERENCES:([sv].[dt]))
|--Clustered Index Seek(OBJECT:([IUS].[nsi].[TableSV].[PK__TableSV__32136E5F50D0E6F9] AS [sv]), SEEK:([sv].[dt] <= '2010-05-25 00:00:00.000') ORDERED BACKWARD)
|--Nested Loops(Left Semi Join, OUTER REFERENCES:([sh].[dt], [sl].[kodA], [sl].[kodB]))
|--Compute Scalar(DEFINE:([Expr1014]=[IUS_NSI].[dbo].[TableSL].[kodC] as [sl].[kodC]))
| |--Nested Loops(Inner Join, OUTER REFERENCES:([sh].[kodA], [sh].[kodB]))
| |--Compute Scalar(DEFINE:([Expr1010]=[IUS].[dbo].[tableSH].[dt] as [sh].[dt], [Expr1011]=[IUS].[dbo].[tableSH].[paramT] as [sh].[paramT], [Expr1012]=[IUS].[dbo].[tableSH].[kodA] as [sh].[kodA], [Expr1013]=[IUS].[dbo].[tableSH].[kodB] as [sh].[kodB]))
| | |--Clustered Index Seek(OBJECT:([IUS].[dbo].[tableSH].[PK_tableSH] AS [sh]), SEEK:([PtnId1002]=RangePartitionNew([IUS].[nsi].[TableSV].[dt] as [sv].[dt],(1),'1996-01-01 00:00:00.000','1996-02-01 00:00:00.000','1996-03-01 00:00:00.000','1996-04-01 00:00:00.000','1996-05-01 00:00:00.000','1996-06-01 00:00:00.000','1996-07-01 00:00:00.000','1996-08-01 00:00:00.000','1996-09-01 00:00:00.000','1996-10-01 00:00:00.000','1996-11-01 00:00:00.000','1996-12-01 00:00:00.000','1997-01-01 00:00:00.000','1997-02-01 00:00:00.000','1997-03-01 00:00:00.000','1997-04-01 00:00:00.000','1997-05-01 00:00:00.000','1997-06-01 00:00:00.000','1997-07-01 00:00:00.000','1997-08-01 00:00:00.000','1997-09-01 00:00:00.000','1997-10-01 00:00:00.000','1997-11-01 00:00:00.000','1997-12-01 00:00:00.000','1998-01-01 00:00:00.000','1998-02-01 00:00:00.000','1998-03-01 00:00:00.000','1998-04-01 00:00:00.000','1998-05-01 00:00:00.000','1998-06-01 00:00:00.000','1998-07-01 00:00:00.000','1998-08-01 00:00:00.000','1998-09-01 00:00:00.000','1998-10-01 00:00:00.000','1998-11-01 00:00:00.000','1998-12-01 00:00:00.000','1999-01-01 00:00:00.000','1999-02-01 00:00:00.000','1999-03-01 00:00:00.000','1999-04-01 00:00:00.000','1999-05-01 00:00:00.000','1999-06-01 00:00:00.000','1999-07-01 00:00:00.000','1999-08-01 00:00:00.000','1999-09-01 00:00:00.000','1999-10-01 00:00:00.000','1999-11-01 00:00:00.000','1999-12-01 00:00:00.000','2000-01-01 00:00:00.000','2000-02-01 00:00:00.000','2000-03-01 00:00:00.000','2000-04-01 00:00:00.000','2000-05-01 00:00:00.000','2000-06-01 00:00:00.000','2000-07-01 00:00:00.000','2000-08-01 00:00:00.000','2000-09-01 00:00:00.000','2000-10-01 00:00:00.000','2000-11-01 00:00:00.000','2000-12-01 00:00:00.000','2001-01-01 00:00:00.000','2001-02-01 00:00:00.000','2001-03-01 00:00:00.000','2001-04-01 00:00:00.000','2001-05-01 00:00:00.000','2001-06-01 00:00:00.000','2001-07-01 00:00:00.000','2001-08-01 00:00:00.000','2001-09-01 00:00:00.000','2001-10-01 00:00:00.000','2001-11-01 00:00:00.000','2001-12-01 00:00:00.000','2002-01-01 00:00:00.000','2002-02-01 00:00:00.000','2002-03-01 00:00:00.000','2002-04-01 00:00:00.000','2002-05-01 00:00:00.000','2002-06-01 00:00:00.000','2002-07-01 00:00:00.000','2002-08-01 00:00:00.000','2002-09-01 00:00:00.000','2002-10-01 00:00:00.000','2002-11-01 00:00:00.000','2002-12-01 00:00:00.000','2003-01-01 00:00:00.000','2003-02-01 00:00:00.000','2003-03-01 00:00:00.000','2003-04-01 00:00:00.000','2003-05-01 00:00:00.000','2003-06-01 00:00:00.000','2003-07-01 00:00:00.000','2003-08-01 00:00:00.000','2003-09-01 00:00:00.000','2003-10-01 00:00:00.000','2003-11-01 00:00:00.000','2003-12-01 00:00:00.000','2004-01-01 00:00:00.000','2004-02-01 00:00:00.000','2004-03-01 00:00:00.000','2004-04-01 00:00:00.000','2004-05-01 00:00:00.000','2004-06-01 00:00:00.000','2004-07-01 00:00:00.000','2004-08-01 00:00:00.000','2004-09-01 00:00:00.000','2004-10-01 00:00:00.000','2004-11-01 00:00:00.000','2004-12-01 00:00:00.000','2005-01-01 00:00:00.000','2005-02-01 00:00:00.000','2005-03-01 00:00:00.000','2005-04-01 00:00:00.000','2005-05-01 00:00:00.000','2005-06-01 00:00:00.000','2005-07-01 00:00:00.000','2005-08-01 00:00:00.000','2005-09-01 00:00:00.000','2005-10-01 00:00:00.000','2005-11-01 00:00:00.000','2005-12-01 00:00:00.000','2006-01-01 00:00:00.000','2006-02-01 00:00:00.000','2006-03-01 00:00:00.000','2006-04-01 00:00:00.000','2006-05-01 00:00:00.000','2006-06-01 00:00:00.000','2006-07-01 00:00:00.000','2006-08-01 00:00:00.000','2006-09-01 00:00:00.000','2006-10-01 00:00:00.000','2006-11-01 00:00:00.000','2006-12-01 00:00:00.000','2007-01-01 00:00:00.000','2007-02-01 00:00:00.000','2007-03-01 00:00:00.000','2007-04-01 00:00:00.000','2007-05-01 00:00:00.000','2007-06-01 00:00:00.000','2007-07-01 00:00:00.000','2007-08-01 00:00:00.000','2007-09-01 00:00:00.000','2007-10-01 00:00:00.000','2007-11-01 00:00:00.000','2007-12-01 00:00:00.000','2008-01-01 00:00:00.000','2008-02-01 00:00:00.000','2008-03-01 ..
| |--Clustered Index Seek(OBJECT:([IUS_NSI].[dbo].[TableSL].[PK_TableSL] AS [sl]), SEEK:([sl].[kodA]=[IUS].[dbo].[tableSH].[kodA] as [sh].[kodA] AND [sl].[kodB]=[IUS].[dbo].[tableSH].[kodB] as [sh].[kodB]), WHERE:([IUS_NSI].[dbo].[TableSL].[Enable] as [sl].[Enable]=(1)) ORDERED FORWARD)
|--Filter(WHERE:([IUS].[dbo].[tableSE].[paramS] as [se].[paramS]=(1)))
|--Sort(TOP 1, ORDER BY:([se].[dt] DESC))
|--Clustered Index Seek(OBJECT:([IUS].[dbo].[tableSE].[PK__tableSE__29AC2CE0] AS [se]), SEEK:([se].[kodA]=[IUS_NSI].[dbo].[TableSL].[kodA] as [sl].[kodA] AND [se].[kodB]=[IUS_NSI].[dbo].[TableSL].[kodB] as [sl].[kodB]), WHERE:([IUS].[dbo].[tableSE].[dt] as [se].[dt]<=[IUS].[dbo].[tableSH].[dt] as [sh].[dt]) ORDERED FORWARD)


2. долгий запрос (order by dt desc)

Table 'tableSE'. Scan count 13575, logical reads 48870, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'TableSL'. Scan count 1, logical reads 16291, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tableSH'. Scan count 8, logical reads 250, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'TableSV'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.


|--Compute Scalar(DEFINE:([Expr1015]=CASE WHEN [Expr1010] IS NULL THEN (0) ELSE (1) END))
|--Top(TOP EXPRESSION:((100)))
|--Merge Join(Left Outer Join, MERGE:([sv].[dt])=([sh].[dt]), RESIDUAL:([IUS].[dbo].[tableSH].[dt] as [sh].[dt]=[IUS].[nsi].[TableSV].[dt] as [sv].[dt]))
|--Clustered Index Seek(OBJECT:([IUS].[nsi].[TableSV].[PK__TableSV__32136E5F50D0E6F9] AS [sv]), SEEK:([sv].[dt] <= '2010-05-25 00:00:00.000') ORDERED BACKWARD)
|--Nested Loops(Left Semi Join, OUTER REFERENCES:([sh].[dt], [sl].[kodA], [sl].[kodB]))
|--Nested Loops(Inner Join, WHERE:([IUS].[dbo].[tableSH].[kodA] as [sh].[kodA]=[IUS_NSI].[dbo].[TableSL].[kodA] as [sl].[kodA] AND [IUS].[dbo].[tableSH].[kodB] as [sh].[kodB]=[IUS_NSI].[dbo].[TableSL].[kodB] as [sl].[kodB]))
| |--Compute Scalar(DEFINE:([Expr1010]=[IUS].[dbo].[tableSH].[dt] as [sh].[dt], [Expr1011]=[IUS].[dbo].[tableSH].[paramT] as [sh].[paramT], [Expr1012]=[IUS].[dbo].[tableSH].[kodA] as [sh].[kodA], [Expr1013]=[IUS].[dbo].[tableSH].[kodB] as [sh].[kodB]))
| | |--Clustered Index Seek(OBJECT:([IUS].[dbo].[tableSH].[PK_tableSH] AS [sh]), SEEK:([PtnId1002] >= (1) AND [PtnId1002] <= (174) AND [sh].[dt] <= '2010-05-25 00:00:00.000') ORDERED BACKWARD)
| |--Compute Scalar(DEFINE:([Expr1014]=[IUS_NSI].[dbo].[TableSL].[kodC] as [sl].[kodC]))
| |--Clustered Index Scan(OBJECT:([IUS_NSI].[dbo].[TableSL].[PK_TableSL] AS [sl]), WHERE:([IUS_NSI].[dbo].[TableSL].[Enable] as [sl].[Enable]=(1)))
|--Filter(WHERE:([IUS].[dbo].[tableSE].[paramS] as [se].[paramS]=(1)))
|--Sort(TOP 1, ORDER BY:([se].[dt] DESC))
|--Clustered Index Seek(OBJECT:([IUS].[dbo].[tableSE].[PK__tableSE__29AC2CE0] AS [se]), SEEK:([se].[kodA]=[IUS_NSI].[dbo].[TableSL].[kodA] as [sl].[kodA] AND [se].[kodB]=[IUS_NSI].[dbo].[TableSL].[kodB] as [sl].[kodB]), WHERE:([IUS].[dbo].[tableSE].[dt] as [se].[dt]<=[IUS].[dbo].[tableSH].[dt] as [sh].[dt]) ORDERED FORWARD)
24 ноя 11, 16:01    [11652723]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Дедушка
Member

Откуда: Город трёх революций
Сообщений: 5122
вас интересует именно "почему" сервер при изменении текста запроса выбрал другой план или что?
24 ноя 11, 16:12    [11652845]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
Дедушка, и это, и каким образом добиться быстрой выборки без указания ненужного поля
но уже нашёл что проглядел - на таблице tableSE был только индекс (kodA, ..., dt) и не было индекса с dt на первом месте
в принципе, тема закрыта :)
24 ноя 11, 16:16    [11652892]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
komrad
Member

Откуда:
Сообщений: 5758
Shakill
Дедушка, и это, и каким образом добиться быстрой выборки без указания ненужного поля
но уже нашёл что проглядел - на таблице tableSE был только индекс (kodA, ..., dt) и не было индекса с dt на первом месте
в принципе, тема закрыта :)


в быстром - nested loops , а в медленном - merge join

можно проверить медленный вариант с добавлением OPTION (LOOP JOIN)
24 ноя 11, 16:21    [11652949]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
komrad
можно проверить медленный вариант с добавлением OPTION (LOOP JOIN)

сработало, медленный вариант стал быстрым даже при старом индексе
24 ноя 11, 16:32    [11653082]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Дедушка
Member

Откуда: Город трёх революций
Сообщений: 5122
komrad
...можно проверить медленный вариант с добавлением OPTION (LOOP JOIN)

вряд ли это "проверить", скорее уж "нагнуть". :)
24 ноя 11, 16:43    [11653187]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
komrad
Member

Откуда:
Сообщений: 5758
Дедушка
komrad
...можно проверить медленный вариант с добавлением OPTION (LOOP JOIN)

вряд ли это "проверить", скорее уж "нагнуть". :)

ну так уж и нагнуть ;)
просто подсказать неразумной машине быстрый вариант - она (оптимизатор) же работает в цейтноте
24 ноя 11, 16:58    [11653306]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Правдоподобность сказанного не означает его верность.
"Идентичность" описанного не означает её оптимальности.
Да, "выпадение" оптимизатора не доказательство ошибочности подхода, но подсказывает о возможности.
Интересно другое почему он выпадает (статистика и т.п., конструкция), как описать задачу по другому и какой подход "кошернее".

После просмотра планов...
С виду баг. PRINT @@Version пжалуста.
Top(Low) + MERGE + LOOP (не MERGE) по идее не должно быть просто никак.
25 ноя 11, 03:08    [11655915]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
Mnior, Microsoft SQL Server 2008 (SP2) - 10.0.4321.0 (Intel X86) Sep 2 2011 17:25:33 а почему такой выбор планов может считаться багом?
25 ноя 11, 11:34    [11657159]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
подметил
Guest
Mnior
Правдоподобность сказанного не означает его верность.
"Идентичность" описанного не означает её оптимальности.
Да, "выпадение" оптимизатора не доказательство ошибочности подхода, но подсказывает о возможности.

Магистр Йода говоришь ты как! ;)
25 ноя 11, 11:37    [11657183]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Shakill
а почему такой выбор планов может считаться багом?
Нет скорее я ошибся.
MERGE вроде как не должен ждать окончания роботы LOOP. Всё вроде как потоком делается и TOP должен тупо обрубить процесс.
Только HASH дву-этапный и ждёт все данные.

Тут дело в скане и ordered. Но к сожадению, у вас план обрезался, притом на важном месте.
Выложите XML (графический) желательно, или полный текстовый (не желательно).
А вот главная их часть:

|--Merge Join(Left Outer Join, MERGE:([sv].[dt])=([sh].[dt]), RESIDUAL:([sh].[dt]=[sv].[dt]))
|--Clustered Index Seek(OBJECT:([PK_TableSV] AS [sv]), SEEK:([sv].[dt] <= '2010-05-25') ORDERED BACKWARD)
|--Nested Loops(Inner Join, WHERE:([sh].[kodA]=[sl].[kodA] AND [sh].[kodB]=[sl].[kodB]))
|--Clustered Index Seek(OBJECT:([PK_tableSH] AS [sh]), SEEK:([PtnId1002] >= (1) AND [PtnId1002] <= (174) AND [sh].[dt] <= '2010-05-25') ORDERED BACKWARD)
|--Clustered Index Scan(OBJECT:([PK_TableSL] AS [sl]), WHERE:([sl].[Enable]=(1)))

|--Nested Loops(Left Outer Join, OUTER REFERENCES:([sv].[dt]))
|--Clustered Index Seek(OBJECT:([PK_TableSV] AS [sv]), SEEK:([sv].[dt] <= '2010-05-25') ORDERED BACKWARD)
|--Nested Loops(Inner Join, OUTER REFERENCES:([sh].[kodA], [sh].[kodB]))
|--Clustered Index Seek(OBJECT:([PK_tableSH] AS [sh]), SEEK:([PtnId1002]=RangePartitionNew([sv].[dt],(1),'1996-01-01',...,'2010-05-25' ??? sh.dt=sv.dt ???) ORDERED ???)
|--Clustered Index Seek(OBJECT:([PK_TableSL] AS [sl]), SEEK:([sl].[kodA]=[sh].[kodA] AND [sl].[kodB]=[sh].[kodB]), WHERE:([sl].[Enable]=(1)) ORDERED FORWARD)

План интересный, да ещё и секции. Совершенно непонятно почему в случае MERGE не сраьатывает SEEK для PK_TableSL т.е.
Вместо поиска по ключу в постоянной таблице делается скан и соединение по ключу LOOP-ом.

Shakill, умоляю, выложите весь план в графике (XML), ваш план показывает баг оптимизатора на простой таблице, который мучает нас всех на временных.
Это очень ценный экземпляр.
29 ноя 11, 11:10    [11675971]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
Mnior, пока что план выложить не могу, но предположу, что в медленном запросе скан TableSL может появляться из-за её размера (всего несколько записей с несколькими интами в каждой).
предикат в быстром запросе (то что вы выделили красным) выглядел как sh.dt <= '2010-05-25' и ORDERED FORWARD
29 ноя 11, 12:43    [11676867]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
locky
Member

Откуда: Харьков, Украина
Сообщений: 62034
почему сразу баг? а вдруг просто перекошенная статистика?
29 ноя 11, 13:11    [11677182]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
Mnior, план быстрого запроса

К сообщению приложен файл (myview_quick.sqlplan - 123Kb) cкачать
29 ноя 11, 13:16    [11677248]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
Mnior, план медленного запроса

К сообщению приложен файл (myview_slow.sqlplan - 37Kb) cкачать
29 ноя 11, 13:17    [11677253]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
locky
почему сразу баг? а вдруг просто перекошенная статистика?
Mnior
Вместо SEEK по кластерному PK в постоянной таблице делается скан по кластерному PK и соединение в LOOP-е по PK
Никакая статистика такое не отмажет.
29 ноя 11, 14:27    [11678005]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
TableSHTableSL
Actual Number of Rows814540721
Estimated Number of Rows63.92125
Mnior
Вместо SEEK по кластерному PK в постоянной таблице делается скан по кластерному PK и соединение в LOOP-е по PK
Вот, сформулировал проблему:
Наличие неактуальной статистики не должно порождать наиболее неоптимальный план в возможных случаях
Т.е. я за более стабильные планы.
Кто за то чтобы вообще запретить выбор SCAN на малых строках ?

Кто скажет на сколько падает скорость при смене SCAN на SEEK? Пруф в студю. Закидайте тыцами.

Вот смотрите, он (оптимизатор) думает, зачем я буду делать 64 раза SEEK в 5 строках, лучше SCAN. @..ть экономия на щепках от спичек.
Ладно, допустим 100500 на 5. И что? Что разница такая сущестченная что SEEK на 5 строках гигантски тормознее чем SCAN???
В этих буферизациях, синхронизация кэша проца, переключения задач бла-бла-бла, больше проседания, чем эти лишние такты.
Если ты (оптимизатор) такой вумный, возми отсортируй эти 5 строк и за-MERGE-и. Или LOOP быстрее MERGE на 5 строках? (Не верю ©)
Как раз для таких случаев.
29 ноя 11, 16:37    [11678999]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
Mnior
TableSHTableSL
Actual Number of Rows814540721
Estimated Number of Rows63.92125
Mnior
Вместо SEEK по кластерному PK в постоянной таблице делается скан по кластерному PK и соединение в LOOP-е по PK
Вот, сформулировал проблему:
Наличие неактуальной статистики не должно порождать наиболее неоптимальный план в возможных случаях
Т.е. я за более стабильные планы.
статистика актуальная. на всякий случай проапдейтил, в долгом запросе в пределах 1% поменялись стоимости Sort на TableSE и Seek на TableSH. в остальном, картина та же
29 ноя 11, 17:48    [11679445]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Shakill
статистика актуальная.
Этим ты хочешь MS добить?
Shakill
в долгом запросе в пределах 1% поменялись стоимости Sort на TableSE и Seek на TableSH. в остальном, картина та же
Нужно не стоимости, а сравнить Estimated Number of Rows сравнить с Actual Number of Rows. Они должны быть порядком.


И, мужики, подключайтесь, 11678999, вопросы же есть, мнения. Или мне опять самим с собой вести беседу?!
30 ноя 11, 10:08    [11681501]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Volochkova
Member

Откуда:
Сообщений: 2321
Интересная вьюха.
А этот кусок на иннер джоин нельзя переписать?
WHERE EXISTS( 
			SELECT *
			FROM ( 
				SELECT TOP 1 *
				FROM BASE1.dbo.tableSE se
				WHERE se.kodA = sl.kodA AND se.kodB = sl.kodB AND se.dt <= sh.dt
				ORDER BY se.dt DESC
			) r
			WHERE r.paramS = 1
			
		)
30 ноя 11, 10:39    [11681635]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
Mnior
Shakill
статистика актуальная.
Этим ты хочешь MS добить?
Shakill
в долгом запросе в пределах 1% поменялись стоимости Sort на TableSE и Seek на TableSH. в остальном, картина та же
Нужно не стоимости, а сравнить Estimated Number of Rows сравнить с Actual Number of Rows. Они должны быть порядком.


И, мужики, подключайтесь, 11678999, вопросы же есть, мнения. Или мне опять самим с собой вести беседу?!


А чего тут подключаться? В данном конкретном примере явно какие то проблемы со статистикой и cardinality, отсюда и все тормоза.
И если только заменить scan 5 строк на seek 5 строк то что-то прям кардинально должно поменятся? Сомневаюсь. Корень проблемы то не в этом.
30 ноя 11, 10:40    [11681636]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
[quot Mind]
Mnior
В данном конкретном примере явно какие то проблемы со статистикой и cardinality, отсюда и все тормоза.
Было же сказано, что статистика актуальна. Или вы имеете ввиду что тут два бага, один ещё и в статистике.

Mind
И если только заменить scan 5 строк на seek 5 строк то что-то прям кардинально должно поменятся? Сомневаюсь.
Вы вообще внимательно читали? Вы хоть планы смотрели? Разжёвываю:

1. На 5 строках нет разницы (это и я доказываю)
2. Скуль меняет SEEK на SCAN (проитив чего я распинаюсь)
3. Статистика "соврала" и там 100500 строк (пофиг почему)
4. 100500 строк со SCAN валят запрос (это факт, см планы, лентяи)
5. SEEK на 100500 строк летает. (Если бы он был бы. см второй запрос)

Mind
Корень проблемы то не в этом.
Ну теперь вы поняли, что как раз в этом то и соль.
30 ноя 11, 11:05    [11681811]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
Mnior
Shakill
статистика актуальная.
Этим ты хочешь MS добить?
Shakill
в долгом запросе в пределах 1% поменялись стоимости Sort на TableSE и Seek на TableSH. в остальном, картина та же
Нужно не стоимости, а сравнить Estimated Number of Rows сравнить с Actual Number of Rows. Они должны быть порядком.

Estimated и Actual в скане остались те же.
но вот чего я не понимаю: в TableSL всего 7 строк, из них фильтру удовлетворяют 5. то есть, Estimated определилось абсолютно точно. а Actual Number (40721) приблизительно совпало с Estimated Number * Number of Executions (8145). кто-то может пояснить?

Volochkova
Интересная вьюха.
А этот кусок на иннер джоин нельзя переписать?
в ней была логическая ошибка, сейчас рабочая вьюха уже не так выглядит. а старый экземпляр держу для этой ветки )
30 ноя 11, 12:21    [11682409]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Shakill
но вот чего я не понимаю: в TableSL всего 7 строк, из них фильтру удовлетворяют 5. то есть, Estimated определилось абсолютно точно. а Actual Number (40721) приблизительно совпало с Estimated Number * Number of Executions (8145). кто-то может пояснить?
Чёрд. Кажись я второй раз ошибся. Из-за того что не видел кусок урезаного плана, не важно.
Ща буду разбирать графический знуля.
Там 13 тысч против 305 строк.
И именно LOOP (не константа) в быстром плане урезает секции (RangePartitionNew) в TableSH. (Сам процесс урезания - аллилуя)
В медленном "бегает" по всем 174 секциям сразу.

Может первое предположение (MERGE + LOOP) всётаки верно ?
А. MERGE дожидается окончания LOOP
Б. TOP не режет процесс
В. TOP не успевает срезать
?

Нужет ответ на вариант А.
Так, сосредоточились.
Актульные план с Actual Rows говорит, что столько-то строк таки и было получено рельано на каждом этапе. Следовательно тормоза были из-за объёмов.
Что-бы определить какой из вариантов (А,Б,В), нужно посмотреть реальные планы без TOP-а (или с большим значением).
Если количество строк для MERGE будет такое же, то верно первоначальное утверждение (А). Иначе проблемы с TOP (Б,В).

PS: Но тынц на SCAN замест SEEK на малых строках всё равно требую.
30 ноя 11, 13:02    [11682800]     Ответить | Цитировать Сообщить модератору
 Re: дополнительное поле в order by ускоряет выборку  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
Mnior
Было же сказано, что статистика актуальна. Или вы имеете ввиду что тут два бага, один ещё и в статистике.

Статистика может и актуальна, хотя мы не знаем с каким sample rate она обновлена, но сюда по тому что таблицы сравнительно не большие это не должно быть проблемой. Но тем не менее правильные оценки сервер не может сделать. Статистика сама по себе далеко не совершенна, хранится всего 200 значений, не отслеживается корреляция значений etc. Так что оптимизатор явно где-то лажает при определении количества строк из TableSH, вопрос - почему? Есть ли какие-то известные проблемы связанные со статистикой на партиционированных таблицах? Особенно как в этом случае, когда партиций под 2 сотни?

Mnior
Вы вообще внимательно читали? Вы хоть планы смотрели? Разжёвываю:

1. На 5 строках нет разницы (это и я доказываю)
2. Скуль меняет SEEK на SCAN (проитив чего я распинаюсь)
3. Статистика "соврала" и там 100500 строк (пофиг почему)
4. 100500 строк со SCAN валят запрос (это факт, см планы, лентяи)
5. SEEK на 100500 строк летает. (Если бы он был бы. см второй запрос)


Так ведь если оценки изначально были бы сделаны правильно, то там был бы другой план. Ну или хотя бы LOOP был бы заменен на HASH. И говорить о том что seek будет быстрее чем scan смысла бы не было.

Mnior
Ну теперь вы поняли, что как раз в этом то и соль.


Даже если обратится с этим вопросом/предложением к мелкомягким, они полюбому укажут в первую очередь на неправильные оценки количества строк (хотя может тут как раз и есть баг). Простым фиксом (scan на seek при количество строк <=5) с их стороны явно не обойтись, а менять всю оценочную модель они уж точно не будут. Там все завязано на предположение что оценки верны, а не на том, что если вдруг статистика наврала тогда лучше сделаем так и так.
30 ноя 11, 21:46    [11686325]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить