Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / дополнительное поле в order by ускоряет выборку / 25 сообщений из 32, страница 1 из 2
24.11.2011, 16:01
    #37542674
Shakill
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
есть вьюха. выборка последних 100 записей к указанной дате стабильно длится 2-3 секунды, если в order by дописываю ещё одно поле (любое, кроме hasFlag), то выборка происходит практически мгновенно

поясните доступно, что произошло
вьюха и запрос
Код: plaintext
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.
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
планы
Код: plaintext
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.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
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)
 
...
Рейтинг: 0 / 0
24.11.2011, 16:12
    #37542692
Дедушка
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
вас интересует именно "почему" сервер при изменении текста запроса выбрал другой план или что?
...
Рейтинг: 0 / 0
24.11.2011, 16:16
    #37542701
Shakill
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
Дедушка, и это, и каким образом добиться быстрой выборки без указания ненужного поля
но уже нашёл что проглядел - на таблице tableSE был только индекс (kodA, ..., dt) и не было индекса с dt на первом месте
в принципе, тема закрыта :)
...
Рейтинг: 0 / 0
24.11.2011, 16:21
    #37542712
komrad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
ShakillДедушка, и это, и каким образом добиться быстрой выборки без указания ненужного поля
но уже нашёл что проглядел - на таблице tableSE был только индекс (kodA, ..., dt) и не было индекса с dt на первом месте
в принципе, тема закрыта :)

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

можно проверить медленный вариант с добавлением OPTION (LOOP JOIN)
...
Рейтинг: 0 / 0
24.11.2011, 16:32
    #37542742
Shakill
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
komradможно проверить медленный вариант с добавлением OPTION (LOOP JOIN)
сработало, медленный вариант стал быстрым даже при старом индексе
...
Рейтинг: 0 / 0
24.11.2011, 16:43
    #37542778
Дедушка
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
komrad...можно проверить медленный вариант с добавлением OPTION (LOOP JOIN)
вряд ли это "проверить", скорее уж "нагнуть". :)
...
Рейтинг: 0 / 0
24.11.2011, 16:58
    #37542805
komrad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
Дедушкаkomrad...можно проверить медленный вариант с добавлением OPTION (LOOP JOIN)
вряд ли это "проверить", скорее уж "нагнуть". :)
ну так уж и нагнуть ;)
просто подсказать неразумной машине быстрый вариант - она (оптимизатор) же работает в цейтноте
...
Рейтинг: 0 / 0
25.11.2011, 03:08
    #37543457
Mnior
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
Правдоподобность сказанного не означает его верность.
"Идентичность" описанного не означает её оптимальности.
Да, "выпадение" оптимизатора не доказательство ошибочности подхода, но подсказывает о возможности.
Интересно другое почему он выпадает (статистика и т.п., конструкция), как описать задачу по другому и какой подход "кошернее".

После просмотра планов...
С виду баг . PRINT @@Version пжалуста.
Top(Low) + MERGE + LOOP (не MERGE) по идее не должно быть просто никак.
...
Рейтинг: 0 / 0
25.11.2011, 11:34
    #37543868
Shakill
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
Mnior, Microsoft SQL Server 2008 (SP2) - 10.0.4321.0 (Intel X86) Sep 2 2011 17:25:33 а почему такой выбор планов может считаться багом?
...
Рейтинг: 0 / 0
25.11.2011, 11:37
    #37543874
подметил
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
MniorПравдоподобность сказанного не означает его верность.
"Идентичность" описанного не означает её оптимальности.
Да, "выпадение" оптимизатора не доказательство ошибочности подхода, но подсказывает о возможности.

Магистр Йода говоришь ты как! ;)
...
Рейтинг: 0 / 0
29.11.2011, 11:10
    #37549408
Mnior
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
Shakillа почему такой выбор планов может считаться багом?Нет скорее я ошибся.
MERGE вроде как не должен ждать окончания роботы LOOP. Всё вроде как потоком делается и TOP должен тупо обрубить процесс.
Только HASH дву-этапный и ждёт все данные.

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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
|--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), ваш план показывает баг оптимизатора на простой таблице, который мучает нас всех на временных.
Это очень ценный экземпляр.
...
Рейтинг: 0 / 0
29.11.2011, 12:43
    #37549655
Shakill
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
Mnior, пока что план выложить не могу, но предположу, что в медленном запросе скан TableSL может появляться из-за её размера (всего несколько записей с несколькими интами в каждой).
предикат в быстром запросе (то что вы выделили красным) выглядел как sh.dt <= '2010-05-25' и ORDERED FORWARD
...
Рейтинг: 0 / 0
29.11.2011, 13:11
    #37549750
locky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
почему сразу баг? а вдруг просто перекошенная статистика?
...
Рейтинг: 0 / 0
29.11.2011, 13:16
    #37549775
Shakill
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
Mnior, план быстрого запроса
...
Рейтинг: 0 / 0
29.11.2011, 13:17
    #37549777
Shakill
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
Mnior, план медленного запроса
...
Рейтинг: 0 / 0
29.11.2011, 14:27
    #37550009
Mnior
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
lockyпочему сразу баг? а вдруг просто перекошенная статистика?Mnior Вместо SEEK по кластерному PK в постоянной таблице делается скан по кластерному PK и соединение в LOOP-е по PK Никакая статистика такое не отмажет.
...
Рейтинг: 0 / 0
29.11.2011, 16:37
    #37550399
Mnior
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
TableSHTableSLActual Number of Rows814540721 Estimated Number of Rows63.92125MniorВместо SEEK по кластерному PK в постоянной таблице делается скан по кластерному PK и соединение в LOOP-е по PKВот, сформулировал проблему:
Наличие неактуальной статистики не должно порождать наиболее неоптимальный план в возможных случаяхТ.е. я за более стабильные планы.
Кто за то чтобы вообще запретить выбор SCAN на малых строках ?

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

Вот смотрите, он (оптимизатор) думает, зачем я буду делать 64 раза SEEK в 5 строках, лучше SCAN. @..ть экономия на щепках от спичек.
Ладно, допустим 100500 на 5. И что? Что разница такая сущестченная что SEEK на 5 строках гигантски тормознее чем SCAN???
В этих буферизациях, синхронизация кэша проца, переключения задач бла-бла-бла, больше проседания, чем эти лишние такты.
Если ты (оптимизатор) такой вумный, возми отсортируй эти 5 строк и за-MERGE-и. Или LOOP быстрее MERGE на 5 строках? (Не верю ©)
Как раз для таких случаев.
...
Рейтинг: 0 / 0
29.11.2011, 17:48
    #37550590
Shakill
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
MniorTableSHTableSLActual Number of Rows814540721 Estimated Number of Rows63.92125MniorВместо SEEK по кластерному PK в постоянной таблице делается скан по кластерному PK и соединение в LOOP-е по PKВот, сформулировал проблему:
Наличие неактуальной статистики не должно порождать наиболее неоптимальный план в возможных случаяхТ.е. я за более стабильные планы.
статистика актуальная. на всякий случай проапдейтил, в долгом запросе в пределах 1% поменялись стоимости Sort на TableSE и Seek на TableSH. в остальном, картина та же
...
Рейтинг: 0 / 0
30.11.2011, 10:08
    #37551359
Mnior
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
Shakillстатистика актуальная.Этим ты хочешь MS добить?
Shakillв долгом запросе в пределах 1% поменялись стоимости Sort на TableSE и Seek на TableSH. в остальном, картина та жеНужно не стоимости, а сравнить Estimated Number of Rows сравнить с Actual Number of Rows . Они должны быть порядком.


И, мужики , подключайтесь, 11678999 , вопросы же есть, мнения. Или мне опять самим с собой вести беседу?!
...
Рейтинг: 0 / 0
30.11.2011, 10:39
    #37551416
Volochkova
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
Интересная вьюха.
А этот кусок на иннер джоин нельзя переписать?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
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 
			
		)
...
Рейтинг: 0 / 0
30.11.2011, 10:40
    #37551417
Mind
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
MniorShakillстатистика актуальная.Этим ты хочешь MS добить?
Shakillв долгом запросе в пределах 1% поменялись стоимости Sort на TableSE и Seek на TableSH. в остальном, картина та жеНужно не стоимости, а сравнить Estimated Number of Rows сравнить с Actual Number of Rows . Они должны быть порядком.


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

А чего тут подключаться? В данном конкретном примере явно какие то проблемы со статистикой и cardinality, отсюда и все тормоза.
И если только заменить scan 5 строк на seek 5 строк то что-то прям кардинально должно поменятся? Сомневаюсь. Корень проблемы то не в этом.
...
Рейтинг: 0 / 0
30.11.2011, 11:05
    #37551480
Mnior
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
[quot Mind]MniorВ данном конкретном примере явно какие то проблемы со статистикой и cardinality, отсюда и все тормоза.Было же сказано, что статистика актуальна. Или вы имеете ввиду что тут два бага, один ещё и в статистике.

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

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

MindКорень проблемы то не в этом.Ну теперь вы поняли, что как раз в этом то и соль.
...
Рейтинг: 0 / 0
30.11.2011, 12:21
    #37551690
Shakill
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
MniorShakillстатистика актуальная.Этим ты хочешь 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Интересная вьюха.
А этот кусок на иннер джоин нельзя переписать? в ней была логическая ошибка, сейчас рабочая вьюха уже не так выглядит. а старый экземпляр держу для этой ветки )
...
Рейтинг: 0 / 0
30.11.2011, 13:02
    #37551806
Mnior
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
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 на малых строках всё равно требую.
...
Рейтинг: 0 / 0
30.11.2011, 21:46
    #37552993
Mind
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
дополнительное поле в order by ускоряет выборку
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) с их стороны явно не обойтись, а менять всю оценочную модель они уж точно не будут. Там все завязано на предположение что оценки верны, а не на том, что если вдруг статистика наврала тогда лучше сделаем так и так.
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / дополнительное поле в order by ускоряет выборку / 25 сообщений из 32, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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