Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.03.22;
Скачать: CL | DM;

Вниз

MSSQL. Посоветуйте индексы на таблицу   Найти похожие ветки 

 
AV ©   (2012-10-19 11:31) [0]

Таблицы большая. Широкая и длинная. Индексов сейчас никаких.
Запрос к ней один, ниже.
Каждый день добавляются строки (несколько десятков тысяч)
Каждый день получаю письмо, где написано время начала и конца запроса.
В первый день запрос идет несколько минут
Потом по нарастающей. К концу месяца не укладывается в ночь.
В начале следующего месяца таблица очищается до 0.
Задача - уложится в ночь.
Запрос не мой, что он делает - не знаю.
Как думаю - надо "правильно" навесить индексы.

SELECT
 MAX(t.[ANI]) Calling,
 RIGHT(MAX(case when t.[CallDisposition]  = 15 then t.[DigitsDialed] else null end), 10) Called,
 (select
     max(ct.[TalkTime])
   from filials_PureDD ct
   where ct.RecoveryKey = MAX(t.RecoveryKey))
     - SUM(case
            when t.[CallDisposition] = 15 then (t.[TalkTime]+t.[DelayTime])
            when t.[CallDisposition] in (28,29) then t.[TalkTime]
            else 0 end
   ) Duration,
  MAX(case when t.[CallDisposition]  = 15 then t.[DateTime] else null end) BeginCall,
  (select top 1 id_sct from ccc.dbo.sct where CallTypeID = MAX(t.[CallTypeID])) ID_SCT,
  MAX(t.[CallTypeID])  [CallTypeID],
  1 as StringForWrite
FROM filials_PureDD t
    join filials_PureDD tt
      on tt.RouterCallKeyDay = t.RouterCallKeyDay and tt.RouterCallKey = t.RouterCallKey
   
where t.[DateTime] >= :DTF
     and tt.[DateTime] <= :DTS
  and t.RouterCallKey <> 0
  and t.RouterCallKeyDay <> 0
  and tt.RouterCallKey <> 0
  and tt.RouterCallKeyDay <> 0
  and tt.CallDisposition=15
group by t.RouterCallKeyDay, t.RouterCallKey


 
AV ©   (2012-10-19 11:52) [1]

DateTime            datetime
RouterCallKey      int
RouterCallKeyDay int
CallTypeID          int
TalkTime            datetime
ANI                   varchar(32)


 
RWolf ©   (2012-10-19 11:56) [2]

ну, напрашиваются индексы на t.RouterCallKeyDay, t.RouterCallKey, раз уж группировка по ним идёт.
индекс на CallDisposition тоже не помешает.


 
AV ©   (2012-10-19 12:13) [3]

>> напрашиваются индексы на t.RouterCallKeyDay, t.RouterCallKey,
тоже думаю
а какие? простые?

+ я пока на DateTime простой ASC повесил

проблема еще в том, что сейчас почти "начало месяца"(там свое исчисление) и таблица почти пуста, едва сотня тысяч записей есть


 
AV ©   (2012-10-19 12:24) [4]

повесил
что имеею (если облажается - не виноват)
 |--Compute Scalar(DEFINE:([Expr1012]=right([Expr1007],(10)), [Expr1018]=[Expr1016]-[Expr1009], [ccc].[dbo].[sct].[id_sct]=[ccc].[dbo].[sct].[id_sct], [Expr1024]=(1)))
      |--Nested Loops(Left Outer Join, OUTER REFERENCES:([Expr1011]))
           |--Nested Loops(Left Outer Join, OUTER REFERENCES:([Expr1008]))
           |    |--Compute Scalar(DEFINE:([Expr1009]=CASE WHEN [Expr1045]=(0) THEN NULL ELSE [Expr1046] END))
           |    |    |--Stream Aggregate(GROUP BY:([t].[RouterCallKey], [t].[RouterCallKeyDay]) DEFINE:([Expr1006]=MAX([ccc].[dbo].[filials_PureDD].[ANI] as [t].[ANI]), [Expr1007]=MAX([Expr1027]), [Expr1008]=MAX([ccc].[dbo].[filials_PureDD].[RecoveryKey] as [t].[RecoveryKey]), [Expr1045]=COUNT_BIG([Expr1028]), [Expr1046]=SUM([Expr1028]), [Expr1010]=MAX([Expr1029]), [Expr1011]=MAX([ccc].[dbo].[filials_PureDD].[CallTypeID] as [t].[CallTypeID])))
           |    |         |--Sort(ORDER BY:([t].[RouterCallKey] ASC, [t].[RouterCallKeyDay] ASC))
           |    |              |--Filter(WHERE:([ccc].[dbo].[filials_PureDD].[RouterCallKeyDay] as [tt].[RouterCallKeyDay]=[ccc].[dbo].[filials_PureDD].[RouterCallKeyDay] as [t].[RouterCallKeyDay] AND [ccc].[dbo].[filials_PureDD].[DateTime] as [tt].[DateTime]<=getdate()-"1900-01-02 00:00:00.000" AND [ccc].[dbo].[filials_PureDD].[CallDisposition] as [tt].[CallDisposition]=(15) AND [ccc].[dbo].[filials_PureDD].[RouterCallKeyDay] as [tt].[RouterCallKeyDay]<>(0)))
           |    |                   |--Nested Loops(Inner Join, OUTER REFERENCES:([Bmk1003], [Expr1044]) WITH UNORDERED PREFETCH)
           |    |                        |--Nested Loops(Inner Join, OUTER REFERENCES:([t].[RouterCallKey]) OPTIMIZED)
           |    |                        |    |--Compute Scalar(DEFINE:([Expr1027]=CASE WHEN [ccc].[dbo].[filials_PureDD].[CallDisposition] as [t].[CallDisposition]=(15) THEN [ccc].[dbo].[filials_PureDD].[DigitsDialed] as [t].[DigitsDialed] ELSE NULL END, [Expr1028]=CASE WHEN [ccc].[dbo].[filials_PureDD].[CallDisposition] as [t].[CallDisposition]=(15) THEN [ccc].[dbo].[filials_PureDD].[TalkTime] as [t].[TalkTime]+[ccc].[dbo].[filials_PureDD].[DelayTime] as [t].[DelayTime] ELSE CASE WHEN [ccc].[dbo].[filials_PureDD].[CallDisposition] as [t].[CallDisposition]=(29) OR [ccc].[dbo].[filials_PureDD].[CallDisposition] as [t].[CallDisposition]=(28) THEN [ccc].[dbo].[filials_PureDD].[TalkTime] as [t].[TalkTime] ELSE (0) END END, [Expr1029]=CASE WHEN [ccc].[dbo].[filials_PureDD].[CallDisposition] as [t].[CallDisposition]=(15) THEN [ccc].[dbo].[filials_PureDD].[DateTime] as [t].[DateTime] ELSE NULL END))
           |    |                        |    |    |--Filter(WHERE:(([ccc].[dbo].[filials_PureDD].[RouterCallKey] as [t].[RouterCallKey]<(0) OR [ccc].[dbo].[filials_PureDD].[RouterCallKey] as [t].[RouterCallKey]>(0)) AND ([ccc].[dbo].[filials_PureDD].[RouterCallKeyDay] as [t].[RouterCallKeyDay]<(0) OR [ccc].[dbo].[filials_PureDD].[RouterCallKeyDay] as [t].[RouterCallKeyDay]>(0))))
           |    |                        |    |         |--Nested Loops(Inner Join, OUTER REFERENCES:([Bmk1000]))
           |    |                        |    |              |--Index Seek(OBJECT:([ccc].[dbo].[filials_PureDD].[IX_filials_PureDD_DateTime] AS [t]), SEEK:([t].[DateTime] >= getdate()) ORDERED FORWARD)
           |    |                        |    |              |--RID Lookup(OBJECT:([ccc].[dbo].[filials_PureDD] AS [t]), SEEK:([Bmk1000]=[Bmk1000]) LOOKUP ORDERED FORWARD)
           |    |                        |    |--Index Seek(OBJECT:([ccc].[dbo].[filials_PureDD].[IX_filials_PureDD_RouterCallKey] AS [tt]), SEEK:([tt].[RouterCallKey]=[ccc].[dbo].[filials_PureDD].[RouterCallKey] as [t].[RouterCallKey]),  WHERE:([ccc].[dbo].[filials_PureDD].[RouterCallKey] as [tt].[RouterCallKey]<>(0)) ORDERED FORWARD)
           |    |                        |--RID Lookup(OBJECT:([ccc].[dbo].[filials_PureDD] AS [tt]), SEEK:([Bmk1003]=[Bmk1003]) LOOKUP ORDERED FORWARD)
           |    |--Stream Aggregate(DEFINE:([Expr1016]=MAX([ccc].[dbo].[filials_PureDD].[TalkTime] as [ct].[TalkTime])))
           |         |--Table Scan(OBJECT:([ccc].[dbo].[filials_PureDD] AS [ct]), WHERE:([ccc].[dbo].[filials_PureDD].[RecoveryKey] as [ct].[RecoveryKey]=[Expr1008]))
           |--Top(TOP EXPRESSION:((1)))
                |--Index Seek(OBJECT:([ccc].[dbo].[sct].[IX_CallType]), SEEK:([ccc].[dbo].[sct].[CallTypeID]=[Expr1011]) ORDERED FORWARD)


 
картман ©   (2012-10-19 19:49) [5]

- SUM(case
           when t.[CallDisposition] = 15 then (t.[TalkTime]+t.[DelayTime])
           when t.[CallDisposition] in (28,29) then t.[TalkTime]
           else 0 end
  ) Duration

я б вычисляемое поле сделал


 
знайка   (2012-10-19 19:56) [6]

А Advisor что говорит?


 
Kerk ©   (2012-10-19 22:15) [7]

http://sqloptimizersqlserver.inside.quest.com/ попробуй :)


 
AV ©   (2012-10-22 08:57) [8]


> Advisor что говорит?

Да тоже и говорит, только больше индексов хочет
НО, имхо, пока нет его смысла слушать. Данных мало, и что он выберет, то не будет оптимальным к концу месяца.

и по той же причине, не доверяю

> Kerk ©   (19.10.12 22:15) [7]


Тут надо эмпирически понять, прочувствовать объемы вперед

пока имею
старт всегда в 0:25:00
20.10.2012 0:28:59  Экспорт закончен
21.10.2012 0:29:37  Экспорт закончен
22.10.2012 - сегодня данных нет, БД отвалилась
(PureDD - это данные с удаленной БД, сегодня линк свалился)

Пока результаты сравнимы с тем, что было


 
AV ©   (2012-10-22 09:02) [9]


> PureDD - это данные с удаленной БД,

т.е. они локальны, таблица тут. Только подтягиваются непосредственно перед выборкой. Пробовал сразу с удаленного запрашивать - вообще, мрак. Уже в середине месяца можно не дождаться.
Соответственно, там я не админ, сделать ничего не могу. Решил тянуть сюда, а тут уже химичить.


 
AV ©   (2012-10-22 09:04) [10]


> - SUM(case
>            when t.[CallDisposition] = 15 then (t.[TalkTime]+t.
> [DelayTime])
>            when t.[CallDisposition] in (28,29) then t.[TalkTime]
>            else 0 end
>   ) Duration
>
> я б вычисляемое поле сделал

меня смущают магические цифры
что-то поменяется - потом не вспомнишь
а пока их видно явно


 
MsGuns ©   (2012-10-22 10:46) [11]

Если еще не все забыл.. Мы вроде избегали конструкции типа Select ...,select
заменяя их на select ... join (select ...) ...


 
AV ©   (2012-10-22 12:49) [12]


> MsGuns ©   (22.10.12 10:46) [11]

да..
и вообще тяжело понимать конструкции типа Select ...,select
но работает, заказчика устраивает - лучше не трогать..
сейчас не дай bug что сломается
..табла вообще 3 раза сама с собой пересекается, это не нормально, по-логике то

и вообще боюсь начинать разбираться что там написано..
>   select ... from ccc.dbo.sct
> Эт куда, что там? дока есть?
> Вот только ничего не спрашивай
> Я не знаю
> запрос их программа выполняет.
> писал им Костя перед увольнением
> Свяжись с ним, может пояснит

Проще подойти к вопросу механически и выполнить тз в рамках постановки - экспорт должен заканчиваться до 8-00. Пусть так и будет. Не будет - буду разбираться далее.


 
stone   (2012-10-22 14:57) [13]


> from filials_PureDD ct
>    where ct.RecoveryKey = MAX(t.RecoveryKey))
>      - SUM(case
>             when t.[CallDisposition] = 15 then (t.[TalkTime]+t.
> [DelayTime])
>             when t.[CallDisposition] in (28,29) then t.[TalkTime]
>
>             else 0 end


С такими конструкциями индекс не поможет


 
AV ©   (2012-10-23 03:42) [14]

Stop at 23.10.2012 0:32:10
в таблице 1182684 записей


 
AV ©   (2012-10-24 08:24) [15]

Stop at 24.10.2012 0:32:42
в таблице 1437130 записей

А может и пойдет все
+30 секунд, на +250 000 записей

тз из двух частей, правда, было
минимум озвучен
максимум - всегда в таблице есть записи за последний месяц + неделя
т.е. за последние примерно 40 дней.
Сегодня день 7ой, запрос идет примерно 7 минут


 
wicked ©   (2012-10-24 11:09) [16]

я бы подошел так:
1 - в начале, середине и в конце "периода" сделать копию таблицы - для того, чтобы можно было прогнать запросы на разных обьемах

2 - со всех копий сделать отчет вот этим страшным запросом - чтобы было понятно, корректно работает новый запрос или нет

3 - оптимизировать запрос до одурения
- убрать лишний join на tt (или обосновать для себя, зачем он нужен);
- поубирать выражения и вызовы функций в секции where - по ним оптимизатор не может применить индекс, даже если он есть;
- проставить индекса на все поля, которые участвуют в join-ах и where
- возможно, проставить filtered index (что то такое в mssql 2008 выдало по запросу conditional index) для тех полей, где много неиспользованых значений (нули в RouterCallKey и RouterCallKeyDay)


 
stone   (2012-10-24 11:49) [17]


> - проставить индекса на все поля, которые участвуют в join-
> ах и where

Есть такая полезная вещь - план выполнения запроса. Хорошо бы ее изучить, прежде, чем создавать индексы на все поля что ни попадя.


 
AV ©   (2012-10-24 12:00) [18]

а в сабже, скорее расчет по средневзвешенной
есть такая.
Хотя, имхо, спорная. Но так работают.


 
AV ©   (2012-10-24 12:09) [19]

не сюда :(

Спасибо.

Придется, видимо, понимать что там и зачем.

Или выделить еще одну таблицу, с данными 2-3 дней, по которой будет идти запрос этого отчета.
А все остальные данные, обозвать архивные, и хранить  в другой таблице.
И сделать вьюшку, как union этих таблиц


 
AV ©   (2012-10-24 12:18) [20]

т.е. мысль разовью.

where t.[DateTime] >= :DTF
    and tt.[DateTime] <= :DTS

:DTF и :DTS
по логу, постоянно требуется за последние сутки
реже, двое суток.
Пусть это будет оперативная таблица
Или Оперативная пусть будет как сейчас, неделя.

Остальное пусть в архивной будет.
Вьюшку обозвать как таблица называется сейчас. Кто захочет покопаться - пусть копается. Внешне разницы не будет.
Так даже можно за 2-3 месяца хранить.



Страницы: 1 вся ветка

Текущий архив: 2013.03.22;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.076 c
8-1228319255
SpecRam
2008-12-03 18:47
2013.03.22
Типа календарный план график


15-1352320203
Юрий
2012-11-08 00:30
2013.03.22
С днем рождения ! 8 ноября 2012 четверг


2-1342612696
Светлана
2012-07-18 15:58
2013.03.22
Контекстное и главное меню


2-1346166751
avil
2012-08-28 19:12
2013.03.22
tcombobox со своими правилами


15-1351157732
cobalt
2012-10-25 13:35
2013.03.22
Зеленое окошко вместо видео.