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

Откуда:
Сообщений: 1086
Есть таблица
CREATE TABLE [dbo].[proc_packs](
	[id] [int] IDENTITY(1,1) NOT NULL,
	[po] [int] NULL,
	[prday] [datetime] NULL,
         ......
 CONSTRAINT [pk_proc_packs] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

--Индекс
CREATE NONCLUSTERED INDEX [ix_proc_packs_prday] ON [dbo].[proc_packs] 
(
	[prday] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]


Что такого могло произойти, что при выполнении такого запроса
select sum(weight) 
,po
from proc_packs where prday>'20130102' 
group by po

В плане видим использование индекса ix_proc_packs_prday

а если prday>'20130101' - сканирование кластерного со всеми вытекающими - запрос выполняется больше 2-х минут (дальше ждать не стал)
PS Как планы опубликовать здесь?
SELECT @@VERSION
Microsoft SQL Server 2008 (SP2) - 10.0.4064.0 (X64) Feb 25 2011 13:56:11 Copyright (c) 1988-2008 Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)
22 янв 13, 14:47    [13809648]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
Ennor Tiegael
Member

Откуда:
Сообщений: 3274
waszkiewicz,

Во втором случае статистика говорит оптимизатору, что данных, подпадающих под условие слишком много, и лукап получится слишком дорогой.

Можно обновить статистику (и регулярно делать это в дальнейшем), а можно сделать покрывающий индекс, если запрос очень частый. Что-нибудь типа
(prday, po) include (weight)
22 янв 13, 14:53    [13809720]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1086
данных за 20130101 нет вообще.
если указать where prday>'20121231' - та же ситуация - сканирование кластерного индекса.
Индексов на таблице и так много (не моя разработка) - навесить еще один - дорого.
select COUNT(id) from proc_packs

(No column name)
43126238

Пока на ум приходит только костыль с фильтрацией по предварительно полученному min(id)
22 янв 13, 15:07    [13809876]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1086
Ennor Tiegael
waszkiewicz,

Во втором случае статистика говорит оптимизатору, что данных, подпадающих под условие слишком много, и лукап получится слишком дорогой.

Можно обновить статистику (и регулярно делать это в дальнейшем), а можно сделать покрывающий индекс, если запрос очень частый. Что-нибудь типа
(prday, po) include (weight)


Сегодня индекс перестроил - не помогает. Пока вот так вышел
from proc_packs with (index(ix_proc_packs_prday))
22 янв 13, 15:12    [13809955]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
Гость333
Member

Откуда:
Сообщений: 3683
waszkiewicz,

Покажите результат выполнения
dbcc show_statistics('dbo.proc_packs', 'ix_proc_packs_prday')
22 янв 13, 15:22    [13810070]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1086
Последние 9 строк

RANGE_HI_KEY RANGE_ROWS EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
2012-12-08 00:00:00.000 118036,4 102249,6 2 59018,19
2012-12-12 00:00:00.000 181594,4 90220,21 3 60531,48
2012-12-19 00:00:00.000 211860,2 48117,45 6 35310,03
2012-12-27 00:00:00.000 223966,5 6014,681 7 31995,21
2013-01-05 00:00:00.000 129974,5 72176,17 6 21662,42
2013-01-13 00:00:00.000 233046,2 30073,4 6 38841,04
2013-01-20 00:00:00.000 172514,7 42102,77 6 28752,45
2013-01-21 00:00:00.000 0 6014,681 0 1
22 янв 13, 15:27    [13810104]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
Гость333
Member

Откуда:
Сообщений: 3683
waszkiewicz
данных за 20130101 нет вообще.

Но оптимизатор при построении плана запроса этого не знает:
waszkiewicz
RANGE_HI_KEY RANGE_ROWS EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
2012-12-27 00:00:00.000 223966.5 6014.681 7 31995.21
2013-01-05 00:00:00.000 129974.5 72176.17 6 21662.42

Я могу ошибаться, но, скорее всего, оптимизатор считает данные внутри интервала — равномерно распределёнными. То есть из 129974.5 записей — 4/9 будут считаться относящимися к 1, 2, 3 и 4 января, а 3/9 — к 2, 3 и 4 января. То есть оптимизатор будет считать, что запросу where prday>'20130102' надо обработать на 129974.5 * 1/9 = 14441,6 записей меньше, чем запросу where prday>'20130101'.

Чему равно Estimated Number of Rows при чтении из таблицы proc_packs в том и в другом плане выполнения?
22 янв 13, 15:56    [13810403]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1086
833,181 и 833,138 (для случая с index_seek)
22 янв 13, 16:10    [13810542]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
Гость333
Member

Откуда:
Сообщений: 3683
waszkiewicz,

А для незахинтованных запросов?
22 янв 13, 17:04    [13810994]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1086
Это именно для них. Для хинтованного - 833,166
22 янв 13, 17:23    [13811108]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
Crimean
Member

Откуда:
Сообщений: 13148
план запроса-то покажите!
22 янв 13, 17:42    [13811233]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1086
Crimean
план запроса-то покажите!

Так я ж спрашивал - как? Рисунки тут не любят, xml - устанет нога читать
22 янв 13, 17:46    [13811251]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
Гость333
Member

Откуда:
Сообщений: 3683
waszkiewicz
Crimean
план запроса-то покажите!

Так я ж спрашивал - как? Рисунки тут не любят, xml - устанет нога читать

К сообщению можно приложить файл. Например, .sqlplan
22 янв 13, 17:47    [13811264]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1086
Ткинте, плз, в пару ссылок, где про понимание планов запросов почитать. И про статистики
22 янв 13, 17:53    [13811317]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1086
Scan тут
+




К сообщению приложен файл (Scan.sqlplan - 15Kb) cкачать
22 янв 13, 18:01    [13811355]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1086
Seek

К сообщению приложен файл (seek.sqlplan - 20Kb) cкачать
22 янв 13, 18:08    [13811399]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
Гость333
Member

Откуда:
Сообщений: 3683
waszkiewicz,

Под "Estimated Number of Rows при чтении из таблицы proc_packs" я имел в виду самую толстую "трубу" в плане запроса (оператор Index Seek для даты "20130102", либо Clustered Index Scan для даты "20130101").

То есть оптимизатор определил, что по условию prday > '20130102' нужно прочитать 599741 записей из таблицы proc_packs, а по условию prday > '20130101' — 614194 записей.

Разница составляет 614194 - 599741 = 14453, что почти сходится с той дельтой, которую я рассчитал в 13810403 (то есть 14441,6).

Стало быть, был пересечён некий порог, при котором оптимизатор заменил одну стратегию доступа к данным — другой стратегией.
22 янв 13, 18:16    [13811454]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1086
Гость333
waszkiewicz,



Стало быть, был пересечён некий порог, при котором оптимизатор заменил одну стратегию доступа к данным — другой стратегией.

И оказался в корне неправ. Может, все-таки сделать "псевдосекционность" и накладывать в запросе условие на id (кластерный индекс)? Ибо при запросе
select min(id) from proc_packs where prday='20130101' 


оптимизатор не затупит?
Или я не прав?
22 янв 13, 18:23    [13811505]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
Гость333
Member

Откуда:
Сообщений: 3683
waszkiewicz
Гость333
оптимизатор заменил одну стратегию доступа к данным — другой стратегией.

И оказался в корне неправ.

Ну не обязательно "в корне". Например, у вас свежие данные лежали в кэше SQL Server, а старые — нет. А если гонять запросы на холодном кэше, то картина может измениться. Или, если всю таблицу загнать в кэш — Clustered Index Scan также может оказаться быстрее.

waszkiewicz
Может, все-таки сделать "псевдосекционность" и накладывать в запросе условие на id (кластерный индекс)?

Попробуйте, потестируйте. Универсальный рецепт тут вряд ли существует.

waszkiewicz
Ибо при запросе
select min(id) from proc_packs where prday='20130101' 

оптимизатор не затупит?

Не очень понял, что вы хотите получить этим запросом. Ведь, по вашим словам, "данных за 20130101 нет вообще"?
22 янв 13, 18:46    [13811655]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
Crimean
Member

Откуда:
Сообщений: 13148
а вы бы индекс таки покрывающим для запроса сделали. или как ту предложили или как вам в плане предлагается
а то пока сервер видит, что ему надо букмаркать - он будет больше склонен к сканам, хотя часто он в этом и неправ, но он так устроен
22 янв 13, 18:53    [13811694]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1086
Гость333
select min(id) from proc_packs where prday='20130101' 

оптимизатор не затупит?

Не очень понял, что вы хотите получить этим запросом. Ведь, по вашим словам, "данных за 20130101 нет вообще"?[/quot]
Хотелось дать "стартовую точку" для кластерного индекса.
22 янв 13, 20:48    [13812128]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
Гость333
Member

Откуда:
Сообщений: 3683
waszkiewicz,

Тогда, наверное,
select min(id) from proc_packs where prday > '20130101' 
?
22 янв 13, 21:07    [13812178]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
Crimean
Member

Откуда:
Сообщений: 13148
Гость333,

а ничего что там в планах букмарк?
22 янв 13, 21:14    [13812194]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
Владимир Затуливетер
Member

Откуда:
Сообщений: 427
waszkiewicz
Гость333
select min(id) from proc_packs where prday='20130101' 


оптимизатор не затупит?

Не очень понял, что вы хотите получить этим запросом. Ведь, по вашим словам, "данных за 20130101 нет вообще"?

Хотелось дать "стартовую точку" для кластерного индекса.


Нормальный вариант, уж куда лучше полного скана кластера.
В любом случае протестировать надо все хорошо.
А вообще я за покрывающий индекс :)
Поменять существующий на этот

CREATE NONCLUSTERED INDEX [ix_proc_packs_prday] ON [dbo].[proc_packs] 
(
	[prday] ASC
)
include ( [weight], [po] );
22 янв 13, 21:16    [13812196]     Ответить | Цитировать Сообщить модератору
 Re: Планы выполнения  [new]
Владимир Затуливетер
Member

Откуда:
Сообщений: 427
Гость333
waszkiewicz,

Тогда, наверное,
select min(id) from proc_packs where prday > '20130101' 

?


а лучше так
select  top (1) id
from    proc_packs
where   prday > '20120201'
order by prday  
22 янв 13, 21:27    [13812217]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить