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

Откуда:
Сообщений: 1197
Привет

Есть вот такой скрипт.
Вопрос: как улучшить производительность?
План показывает что в Select 62% уходит на Sort. причем на реальных данных я вижу, что проседает база именно на извелечении productGroup из #models.

Подскажите как улучшить?

+
create table #sales 
(
  storeCode varchar(20),
  saledate char(8), 
  articul varchar(10),
  itemsQty int
)
CREATE NONCLUSTERED INDEX [NonClusteredIndex-20130904-105520] ON #sales
(
	[SaleDate] ASC,
	storeCode ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO


create table #models
(
  articul varchar(10),
  productGroup  varchar(10)
)
CREATE NONCLUSTERED INDEX [NonClusteredIndex-20130904-105521] ON #models
(
	articul ASC,
	productGroup ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO

insert #sales select 'A123', '20130801', 'Tv1', 1
insert #sales select 'A123', '20130802', 'Tv1', 1
insert #sales select 'A123', '20130803', 'Tv1', 1
insert #sales select 'A123', '20130804', 'Tv1', 1
insert #sales select 'A126', '20130801', 'Tv1', 1
insert #sales select 'A126', '20130802', 'Tv1', 1
insert #sales select 'A126', '20130803', 'Tv1', 1
insert #sales select 'A126', '20130804', 'Tv1', 1
insert #sales select 'A123', '20130801', 'Tv2', 1
insert #sales select 'A123', '20130802', 'Tv2', 1
insert #sales select 'A123', '20130803', 'Tv3', 1
insert #sales select 'A123', '20130804', 'Tv4', 1
insert #sales select 'A126', '20130801', 'Tv5', 1
insert #sales select 'A126', '20130802', 'Tv6', 1
insert #sales select 'A126', '20130803', 'Tv7', 1
insert #sales select 'A126', '20130804', 'Tv8', 1

insert #sales select 'A126', '20130804', 'VIDEO', 1

insert #models select 'Tv1', 'Tv'
insert #models select 'Tv2', 'Tv'
insert #models select 'Tv3', 'Tv'
insert #models select 'Tv4', 'Tv'
insert #models select 'Tv5', 'Tv'
insert #models select 'Tv6', 'Tv'
insert #models select 'Tv7', 'Tv'
insert #models select 'Tv8', 'Tv'

insert #models select 'Av7', 'Av'
insert #models select 'Av8', 'Av'

select max(s.saledate), max(s.itemsQty), s.articul, ISNULL(m.productGroup, 'OTHER') as productGroup, s.storecode
from #sales s 
 left join #models m 
  on s.articul = m.articul
where saledate between '20130802' and '20130803'
group by s.storecode, s.articul, m.productGroup
4 сен 13, 11:03    [14792944]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
Гость333
Member

Откуда:
Сообщений: 3683
relief
причем на реальных данных я вижу, что проседает база именно на извелечении productGroup из #models.

Это вы как определили?
Actual Execution Plan можете выложить?
4 сен 13, 11:15    [14792997]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
relief
Member

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

приложил

К сообщению приложен файл (plan.sqlplan - 33Kb) cкачать
4 сен 13, 11:24    [14793060]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 34008
Блог
relief,

это точно актуальный план?
фактическое количество строк в продажах = 8?
4 сен 13, 11:25    [14793069]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
Критик,

ето актуальный план к примеру
4 сен 13, 11:26    [14793074]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
а вы вообще зачем дату как строку то храните ??? Да и строковые идентификаторы - выглядт не лучшим образом по факту
4 сен 13, 11:28    [14793089]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
relief
Member

Откуда:
Сообщений: 1197
Maxx
а вы вообще зачем дату как строку то храните ??? Да и строковые идентификаторы - выглядт не лучшим образом по факту


я не могу менять структуру базы
4 сен 13, 11:30    [14793111]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
aleks2
Guest
А нефиг JOIN внутрь группировки совать.

PS. #Sales нибось на порядки больше #models.
4 сен 13, 11:31    [14793114]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
Гость333
Member

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

приложил

Вы же писали, что "проседает база". А приложили план запроса, в котором джойнятся таблицы из восьми и восьмидесяти строк. Сомнительно, чтобы на таких объёмах у вас что-то "проседало". Можно увидеть актуальный план действительно "проседающего" запроса?
4 сен 13, 11:37    [14793154]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 34008
Блог
create index idx273 on #sales (
	storeCode ASC,
    articul
) include ([SaleDate],itemsQty)

select s.saledate, s.itemsQty, s.articul, ISNULL(m.productGroup, 'OTHER') as productGroup, s.storecode
from (select max(s.saledate) saledate, max(s.itemsQty) itemsQty, s.articul, s.storecode
        from #sales s
        where saledate between '20130802' and '20130803'
        group by s.articul, s.storecode) s 
 left join #models m 
  on s.articul = m.articul
4 сен 13, 11:37    [14793155]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
relief
Member

Откуда:
Сообщений: 1197
aleks2
А нефиг JOIN внутрь группировки совать.

PS. #Sales нибось на порядки больше #models.


да. порядок - десятки миллионов в sales но там есть индексы, которые я показал
4 сен 13, 11:38    [14793163]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 34008
Блог
relief
да. порядок - десятки миллионов в sales но там есть индексы, которые я показал


план и от количества строк зависит, например, вид соединения в плане будет другой...
4 сен 13, 11:39    [14793167]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
Exproment
Member

Откуда:
Сообщений: 416
Критик, ваш запрос не является аналогичным исходному запросу - в нем нет группировки по
#models.productGroup => результаты разные.
4 сен 13, 12:06    [14793397]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 34008
Блог
какую цифру вернет?

select count(*)
  from (select articul,productGroup
          from #models
          group by articul,productGroup
          having count(*)>1
       ) as x
4 сен 13, 12:25    [14793561]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
aleks2
Guest
Exproment
Критик, ваш запрос не является аналогичным исходному запросу - в нем нет группировки по
#models.productGroup => результаты разные.

Ну дык, вставь?
4 сен 13, 12:27    [14793581]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
relief
Member

Откуда:
Сообщений: 1197
Критик
relief
да. порядок - десятки миллионов в sales но там есть индексы, которые я показал


план и от количества строк зависит, например, вид соединения в плане будет другой...


план выложить не могу. но вид соединения действительно меняется на right.
но та же сортировка всё равно 38% занимает
4 сен 13, 12:42    [14793707]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
Exproment
Member

Откуда:
Сообщений: 416
aleks2
Ну дык, вставь?

В приведенном решении не меняя концептуально сам запрос - нельзя вставить дополнительную агрегацию по полю из внешнего запроса, при этом возвращая данные внутреннего запроса.

У меня возник вопрос, который возможно разрешит суть задачи.

Допустим необходимо выполнить запрос(упростил исходный).
select	max(s.saledate), s.articul, s.storecode
from	#sales s 
where	saledate between '20130802' and '20130803'
group by s.storecode, s.articul

Имеем предикат по saledate и группировку по storecode и articul. Соответственно что нам надо в идеальном мире -
1) index seek по предикату с saledate
2) Предварительная сортировка по полям storecode, articul.

Делаем индекс
create index IX_#sales_storecode_articul on #sales(SaleDate, storecode, articul);

Чтобы была возможность использовать поиск в индексе, поле saledate должно быть левым полем индекса. Но тогда Index Seek возвращает данные не отсортированные по storecode, articul. => имеем картину:
1) Вариант 1 - имеем index seek, но выполняем сортировку перед stream aggreagate
2) Вариант 2 - не имеем index seek, но не выполняем сортировку перед stream aggreagate

Вопрос - можно ли найти в данной ситуации идеальное решение, чтобы и index seek был и stream aggreagate без сортировки(на лету). Не много не понимаю, почему sql server не может выполняя поиск по saledate вытащить из индекса данные, сразу отсортированные по storecode, articul ?

P.S. Hash Aggregate не предлагать
4 сен 13, 12:43    [14793710]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
Exproment
Member

Откуда:
Сообщений: 416
relief
план выложить не могу. но вид соединения действительно меняется на right.

Видимо из соображений безопасности ? Есть утилиты, которые заменяют все знчимые имена в плане на вида "Таблица1", "Поле1" и т.д.
4 сен 13, 12:44    [14793718]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
relief
Member

Откуда:
Сообщений: 1197
Exproment
relief
план выложить не могу. но вид соединения действительно меняется на right.

Видимо из соображений безопасности ? Есть утилиты, которые заменяют все знчимые имена в плане на вида "Таблица1", "Поле1" и т.д.


да. какие утилиты?
4 сен 13, 12:48    [14793739]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
Exproment
Member

Откуда:
Сообщений: 416
relief
да. какие утилиты?

sql sentry plan explorer
4 сен 13, 12:55    [14793793]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
relief
Member

Откуда:
Сообщений: 1197
Exproment
relief
да. какие утилиты?

sql sentry plan explorer


спасибо за наводку.

план в аттаче
4 сен 13, 13:35    [14793987]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
relief
Member

Откуда:
Сообщений: 1197
relief
Exproment
пропущено...

sql sentry plan explorer


спасибо за наводку.

план в аттаче


приложил

К сообщению приложен файл (Plan_Anonymized.sqlplan - 9Kb) cкачать
4 сен 13, 13:36    [14793993]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
aleks2
Guest
Ну нафега этот план? Тут и так усе ясно.

1. Если ты упорно хочешь оставить "свой, дурной, но родной" запрос.

CREATE UNIQUE CLUSTERED INDEX [NonClusteredIndex-20130904-105520] ON #sales
(
	[SaleDate] ASC,
	articul ASC
)GO


CREATE UNIQUE CLUSTERED INDEX [NonClusteredIndex-20130904-105521] ON #models
(
	articul ASC,
	productGroup ASC
)GO


2. Но лучче написать запрос правильно. Индесы те же.
4 сен 13, 13:45    [14794021]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
relief
Member

Откуда:
Сообщений: 1197
aleks2
Ну нафега этот план? Тут и так усе ясно.

1. Если ты упорно хочешь оставить "свой, дурной, но родной" запрос.

CREATE UNIQUE CLUSTERED INDEX [NonClusteredIndex-20130904-105520] ON #sales
(
	[SaleDate] ASC,
	articul ASC
)GO


CREATE UNIQUE CLUSTERED INDEX [NonClusteredIndex-20130904-105521] ON #models
(
	articul ASC,
	productGroup ASC
)GO


2. Но лучче написать запрос правильно. Индесы те же.


как правильно написать?
4 сен 13, 13:50    [14794045]     Ответить | Цитировать Сообщить модератору
 Re: Улучшение производительности селекта  [new]
aleks2
Guest
Как-то так...
https://www.sql.ru/forum/1041362/medlennyy-select-s-gruppirovkoy?hl=aleks2
4 сен 13, 13:53    [14794068]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить