Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Помогите разобраться с оптимизацией запроса. / 13 сообщений из 13, страница 1 из 1
09.07.2020, 15:42
    #39977799
teCa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться с оптимизацией запроса.
Всем привет, практике в оптимизации запросов практически не имею, помогите советом.

Вот сам запрос:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
SELECT TOP(1000)
        [a].[Id]
       ,[s].[Id] AS SiteId
       ,[s].
       ,[s].[Name]
       ,[s].[GeoObjectId]
       ,[s].[CountryId]
       ,[ab].[Author]                
       ,[ab].[Body]
       ,[ab].[Date]
       ,[ab].[Rubric]
       ,[ab].[Data]
       ,[a].[LocalTimeStamp] AS [TimeStamp]
FROM        [dbo].[Article]      AS [a]  (NOLOCK)
LEFT JOIN   [dbo].[StartUrl]     AS [su] (NOLOCK) ON [a].[StartUrlId] = [su].[Id]
INNER JOIN  [dbo].[Site]         AS [s]         (NOLOCK) ON ISNULL([su].[SiteId], [a].[SiteId]) = [s].[Id]
INNER JOIN  [dbo].[ArticleBlobs] AS [ab] (NOLOCK) ON [ab].[ArticleId] = [a].[id]
WHERE [a].[Id] > 1042404362 AND [a].[LocalTimeStamp] >= '06.07.2020' AND [a].[LocalTimeStamp] <= '07.07.2020'
  AND [a].[StatusId] != 11
  AND [s].[StatusId] = 0 -- только активные сайты
  AND [ab].[Data] IS NOT NULL
  AND LEN([Data].value('(/article/fields/field[@name="Date"])[1]', 'nvarchar(64)')) = 19
ORDER BY [a].[LocalTimeStamp] ASC



Подскажите, с чего начать на конкретном примере, на что в первую очередь стоит обратить внимание в текущем плане?
Благодарю.
...
Рейтинг: 0 / 0
09.07.2020, 16:22
    #39977810
Владислав Колосов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться с оптимизацией запроса.
teCa,

'06.07.2020' - так даты нельзя записывать, надо '20200706'. Это общее замечание.

А какие хотите получить рекомендации - как научиться составлять индексы? Сомневаюсь, что это тема для форумного обсуждения.
...
Рейтинг: 0 / 0
09.07.2020, 16:27
    #39977815
teCa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться с оптимизацией запроса.
Владислав Колосов,

Скорее, рекомендации по чтению плана запроса. Если даже, в моем случае, эта тема про индексы, то как вы сделали этот вывод из текущего плана?
...
Рейтинг: 0 / 0
09.07.2020, 16:45
    #39977827
felix_ff
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться с оптимизацией запроса.
teCa,

у вас в плане запроса применяется оператор соединения NL без предиката соединения, это плохо.

при этом правом входе у него ветка из ClusteredIndexScan => TableSpool

все из-за предиката соедениния:
Код: sql
1.
ISNULL([su].[SiteId], [a].[SiteId]) = [s].[Id]



постарайтесь переписать запрос без условного предиката соединения
...
Рейтинг: 0 / 0
09.07.2020, 17:15
    #39977835
PizzaPizza
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться с оптимизацией запроса.
Код: sql
1.
[a].[LocalTimeStamp] >= '06.07.2020' AND [a].[LocalTimeStamp] <= '07.07.2020'


название колонки не отражает формат фильтрации по ней, и поэтому хочется уточнить, нет ли там времени в колонке и если есть, то в данном запросе какой интервал имеется ввиду.
...
Рейтинг: 0 / 0
10.07.2020, 07:13
    #39977972
a_voronin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться с оптимизацией запроса.
teCa,

Вам сейчас будут советовать, как переписать запрос, а я вот вам дам иной совет. Сделайте параллельно вашим таблицам, некую таблицу, ориентированную на поиск. Денормализованную (с уже выполненными JOIN), возможно колоночную.

Там такие вещи, предрассчитайте

[Data].value('(/article/fields/field[@name="Date"])[1]', 'nvarchar(64)')

Сделайте схему звезда, если надо.
...
Рейтинг: 0 / 0
10.07.2020, 08:01
    #39977980
skyANA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться с оптимизацией запроса.
a_voronin
teCa,

Вам сейчас будут советовать, как переписать запрос, а я вот вам дам иной совет. Сделайте параллельно вашим таблицам, некую таблицу, ориентированную на поиск. Денормализованную (с уже выполненными JOIN), возможно колоночную.

Там такие вещи, предрассчитайте

[Data].value('(/article/fields/field[@name="Date"])[1]', 'nvarchar(64)')

Сделайте схему звезда, если надо.

Вроде ТС хочет научиться оптимизации запросов, понимать план выполнения.

Денормализация - это отдельная тема.

И при чём тут схема звезда?
...
Рейтинг: 0 / 0
10.07.2020, 13:18
    #39978103
teCa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться с оптимизацией запроса.
Почитал все комментарии, но пока все равно не понятно. Методом манипуляций, понял только, что 2 JOIN отрабатывают быстро, 3 JOIN - медленно, причем всё равно, какие таблицы подключаю, любые 2 - быстро, стоит подключить 3ю - начинаются тормоза.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
SELECT TOP(1000)
        [a].[Id]
       ,[s].[Id] AS SiteId
       ,[s].
       ,[s].[Name]
       ,[s].[GeoObjectId]
       ,[s].[CountryId]
       --,[ab].[Author]                
       --,[ab].[Body]
       --,[ab].[Date]
       --,[ab].[Rubric]
       --,[ab].[Data]
       ,[a].[LocalTimeStamp] AS [TimeStamp]
FROM        [dbo].[Article]      AS [a]  (NOLOCK)
LEFT JOIN   [dbo].[StartUrl]     AS [su] (NOLOCK) ON [a].[StartUrlId] = [su].[Id]
INNER JOIN  [dbo].[Site]         AS [s]         (NOLOCK) ON ISNULL([su].[SiteId], [a].[SiteId]) = [s].[Id]
--INNER JOIN  [dbo].[ArticleBlobs] AS [ab] (NOLOCK) ON [ab].[ArticleId] = [a].[id]
WHERE [a].[Id] > 1042404362 AND [a].[LocalTimeStamp] >= '06.07.2020' AND [a].[LocalTimeStamp] <= '07.07.2020'
  AND [a].[StatusId] != 11
  AND [s].[StatusId] = 0 -- только активные сайты
  --AND [ab].[Data] IS NOT NULL
  --AND LEN([Data].value('(/article/fields/field[@name="Date"])[1]', 'nvarchar(64)')) = 19
ORDER BY [a].[LocalTimeStamp] ASC



Например в таком виде, запрос отрабатывает бысто.
...
Рейтинг: 0 / 0
10.07.2020, 13:19
    #39978104
teCa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться с оптимизацией запроса.
teCa,

Не понятно, почему третий джойн "ломает" запрос.
...
Рейтинг: 0 / 0
10.07.2020, 13:32
    #39978113
londinium
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться с оптимизацией запроса.
Код: sql
1.
ON ISNULL([su].[SiteId], [a].[SiteId]) = [s].[Id]


Есть версия, что это не самая удачная конструкция
...
Рейтинг: 0 / 0
10.07.2020, 13:38
    #39978118
Гавриленко Сергей Алексеевич
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться с оптимизацией запроса.
teCa
teCa,

Не понятно, почему третий джойн "ломает" запрос.
Потму что вы предыдущим джоином "сломали" оптимизатор. Фиксируйте план хинтами, если знаете, какие стратегии объединения правильные, материализуйте промежуточные результаты, не пишите кривые предикаты -- в общем, все на ваш выбор.
...
Рейтинг: 0 / 0
10.07.2020, 14:09
    #39978136
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться с оптимизацией запроса.
teCa
Не понятно, почему третий джойн "ломает" запрос.
Запрос ломает не 3-й джоин, а top()/order by, предикат LEN([Data].value('(/article/fields/field[@name="Date"])[1]', 'nvarchar(64)')) = 19 и не первой свежести для статистика для [dbo].[Site].
Из-за ошибочных оценок кардинальности оптимизатор выбирает cross join для [dbo].[Site] с последующей фильтрацией.
...
Рейтинг: 0 / 0
10.07.2020, 15:04
    #39978174
aleks222
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите разобраться с оптимизацией запроса.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
with s as ( select * from [dbo].[Site] with(NOLOCK) where StatusId = 0 ) -- только активные сайты
   , a as ( select * from [dbo].[Article] with(NOLOCK) where [Id] > 1042404362 AND [LocalTimeStamp] >= '06.07.2020' AND [LocalTimeStamp] <= '07.07.2020' AND [StatusId] != 11 )
   , ab as ( select * from [dbo].[ArticleBlobs] with(NOLOCK) where [Data] IS NOT NULL AND LEN([Data].value('(/article/fields/field[@name="Date"])[1]', 'nvarchar(64)')) = 19 )
SELECT TOP(1000)
        [a].[Id]
       , isnull( [ssu].[Id], [sa].[Id]) AS SiteId
       , isnull( ssu., [sa]. ) as 
       ,[s].[Name]...
       ,[s].[GeoObjectId]...
       ,[s].[CountryId]..
       --,[ab].[Author]                
       --,[ab].[Body]
       --,[ab].[Date]
       --,[ab].[Rubric]
       --,[ab].[Data]
       ,[a].[LocalTimeStamp] AS [TimeStamp]
FROM a
	LEFT JOIN [dbo].[StartUrl] AS [su] (NOLOCK) ON [a].[StartUrlId] = [su].[Id]
	left outer JOIN s AS [ssu] ON [su].[SiteId] = [ssu].[Id]
	left outer JOIN s AS [sa] ON [a].[SiteId] = [sa].[Id] and [ssu].[Id] is null
	INNER JOIN ab ON [ab].[ArticleId] = [a].[id]
WHERE (ssu.id is not null or [sa].[Id] is not null)
ORDER BY [a].[LocalTimeStamp] ASC



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


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