powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / ASA9.0.1 Помогите с оптимальными индексами на большой таблице
39 сообщений из 39, показаны все 2 страниц
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32665946
Фотография Vovaka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть таблица

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
create table voip.cdr_billing (
  id               integer primary key not null default autoincrement,
  cdrid            integer references voip.cdr_tel(id) on delete cascade on update cascade,
  accounttype      integer,       
  accountid        integer,
  datetime         datetime,
  e164prefix       char( 16 ),
  callduration     integer,
  billingduration  integer,
  minuteprice      double,
  callprice        double,
  currencyrate     double
);  

кол-во данных до нескольких десятков миллионов
запросы вида:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
select
(select first g.name as lang from tel.globalprefixgroup g, tel.globalprefix p where
g.id = prefixgroupid and prefix = e164prefix and prefixgroupsetid =  6 ) lang, 
e164prefix as _e164prefix, minuteprice/currencyrate as minuteprice, count(*), 
sum(billingduration)/ 60  as sbd, sum(callprice/currencyrate) as _sum, sum(callduration)/ 60  as scd 
from voip.cdr_billing where datetime between '2004-08-01' and '2004-08-02' and accounttype in ( 2 ,  3 ,  4 ,  8 ) and accountid =  33  
group by _e164prefix, minuteprice
order by  2 

в запросах меняется дата/время , набор значений accounttype и значение accountid

за сутки вставляется примерно 400000 записей, accounttype может принимать десяток значений, accountid - десятки(сотни) тысяч, но регулярные обращения к первой тысяче, есть и другие запросы, но эти - основные
сейчас сделаны
Код: plaintext
1.
2.
3.
create index voip_cdr_billing_e164prefix on voip.cdr_billing (e164prefix);
create index voip_cdr_billing_accountid_accounttype on voip.cdr_billing (accounttype, accountid);
create index voip_cdr_billing_datetime on voip.cdr_billing (datetime);
create index voip_cdr_billing_minuteprice on voip.cdr_billing (minuteprice);
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32665969
_Dog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
A IndexConsultant не помогает?
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32666096
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для начала нужно однозначно переписать запрос и вывести подзапрос из секции SELECT в секцию FROM. Сейчас сто процентов в плане запросов стоит Subquery, который выполняется на каждую строку основного запроса. Нужно от него однозначно избавиться. Попробуйте его соеденить с основным запросом через INNER JOIN или LATERAL, смотря что будет красивее в плане запроса и эффективнее.

P.S. На будующее лучше всего показывать в сообщение помимо структуры таблицы, созданных индексов и текста запроса еще возвращаемый план запроса. Иначе без этого сложно сказать, в чем собака порылась :)
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32666140
_Dog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
при таком росте данных, если позволяет бюджет, советую посмотреть Sybase IQ.
Анализ CDR'ов/логов - типичная задача для IQ.
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32666375
Фотография Vovaka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробую переписать сейчас запрос, тогда план выложу, просто я нифига в нем еще не разбираюсь пока :), девятку только поставили, а раньше все по интуиции больше делалось ...

IQ во первых ОЧЕНЬ дорого, во вторых он не потянет такой объем вставляемых данных, insert очень долго проходит ...
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32666392
Фотография Vovaka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, индексконсультант посоветовал кластерный составной индекс
(accounttype, accountid, datetime)
но что-то стремно как-то ....
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32666493
_Dog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IQ должен стоять "рядом", как база для анализа/репортинга и т.п.
Перекинуть 400000 записей из АСА в IQ - дело 3-5 сек. Можно как bulk load так и proxy (insert into location).
Цена - это конечно :) Вам решать :) но такие селекты решаются в пределах <X сек (с 1CPU, 512Мб RAM, 40mln row) и еще быстрее на нормальном железе
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32666546
_Dog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VovakaДа, индексконсультант посоветовал кластерный составной индекс
(accounttype, accountid, datetime)
но что-то стремно как-то ....

Это ASKRUS спец по индексам. :) Ждите вердикта.
Думаю один кластерный индех не помешает, но довольно сильно увеличит базу.
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32667173
Фотография Vovaka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
сделал составной индекс по трем полям, но не кластерный - оптимизатор им не пользуется, пользуется индексом по дате/времени с селективностью 94% .... чего-то то не понимаю совсем :(
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32667286
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Переписали ли Вы запрос ?
2. Если переписали, то ждем его новый текст и его план запроса.
- иначе ничего сказать по поводу того, нужен ли кластерный индекс и по каким полям нельзя.
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32667354
Фотография Vovaka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А что такое UltraPlan ? Видимо я не туда посмотрел, потому как результаты в Plan и UltraPlan разные ...
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32667372
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VovakaЕсть таблица

за сутки вставляется примерно 400000 записей, accounttype может принимать десяток значений, accountid - десятки(сотни) тысяч, но регулярные обращения к первой тысяче, есть и другие запросы, но эти - основные.

сейчас сделаны


create index voip_cdr_billing_accountid_accounttype on voip.cdr_billing (accounttype, accountid);

Это бесполезный (или малополезный) индекс, исходя из того, что ты сообщил.
Или тут перепутан порядок полей в посте или при создании индекса.
( accountid,accounttype)???;

Индексы по e164prefix и minuteprice для ЭТОГО запроса тоже малополезны - ему собственно нужен индекс по accountid.
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32667376
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
(ой, добавочка)
... или datetime
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32667394
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ASCRUSДля начала нужно однозначно переписать запрос и вывести подзапрос из секции SELECT в секцию FROM. Сейчас сто процентов в плане запросов стоит Subquery, который выполняется на каждую строку основного запроса. Нужно от него однозначно избавиться. Попробуйте его соеденить с основным запросом через INNER JOIN или LATERAL, смотря что будет красивее в плане запроса и эффективнее.

Как-то не очень бы согласился я :
Из запроса не понятно, коррелированный подзапрос там или нет.
Кажется, что нет. Если да, то куда его не ставь - все едино.

Если запрос некоррелированный, то с какой такой стати ASA его будет для каждой строчки выполнять ? Или оно такое глупое, что ONCE AGREGATE не понимает ?
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32667395
Фотография Vovaka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv VovakaЕсть таблица

за сутки вставляется примерно 400000 записей, accounttype может принимать десяток значений, accountid - десятки(сотни) тысяч, но регулярные обращения к первой тысяче, есть и другие запросы, но эти - основные.

сейчас сделаны


create index voip_cdr_billing_accountid_accounttype on voip.cdr_billing (accounttype, accountid);

Это бесполезный (или малополезный) индекс, исходя из того, что ты сообщил.
Или тут перепутан порядок полей в посте или при создании индекса.
( accountid,accounttype)???;

Индексы по e164prefix и minuteprice для ЭТОГО запроса тоже малополезны - ему собственно нужен индекс по accountid.

Перепутано здесь :(
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32667437
Фотография Vovaka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivИндексы по e164prefix и minuteprice для ЭТОГО запроса тоже малополезны - ему собственно нужен индекс по accountid.

блин, я думал они будут помогать делать group by e164prefix, minuteprice
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32667519
Фотография Vovaka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ASCRUS1. Переписали ли Вы запрос ?
2. Если переписали, то ждем его новый текст и его план запроса.
- иначе ничего сказать по поводу того, нужен ли кластерный индекс и по каким полям нельзя.

А что из плана нужно выложить ? там так всего много ...
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32667645
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторКак-то не очень бы согласился я :

Из запроса не понятно, коррелированный подзапрос там или нет.
Кажется, что нет. Если да, то куда его не ставь - все едино.
В скрипте подзапроса в WHERE стоит "prefix = e164prefix". Так что не едино. Во вторых ASA после переноса запроса в FROM уведет его в дерево главного плана, убрав Subquery, что уже прибавит скорости не мало. Так что переписывать нужно в обязку.

авторА что из плана нужно выложить ? там так всего много ...
Ставим в ISQL опцию Long Plan, нажимаем F5 и копируем результат сюда. По другому не разберешься.
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32667679
Фотография Vovaka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Начал уже писать, что не всегда используется этот индекс, что возникают ситуации, когда появляется table scan, если в этом примере поменять accountid на определенное значение - то индексскан почему то уже не используется...

в общем потом попробовал еще пару раз - table scan пропало ... теперь еще непонятней стало :)

вот план
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
( Plan [ Total Cost Estimate:  497 . 43028  ] 
  ( WorkTable
    ( Sort
      ( HashGroupBy
        ( NestedLoopsJoin[ TRUE ]
          ( InList )
          ( IndexScan cdr_billing voip_cdr_billing_accountid_accounttype_datetime )
        )
      )
    )
  )
)
)

так полезен ли будет кластерный индекс ?
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32667796
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vovaka MasterZivИндексы по e164prefix и minuteprice для ЭТОГО запроса тоже малополезны - ему собственно нужен индекс по accountid.

блин, я думал они будут помогать делать group by e164prefix, minuteprice

Ага, жди ...
Подумай, чему они будут помогать ? Ну, не будет сервер сортировать набор данных при группировке, читая ВСЮ ТВОЮ ТАБЛИЦУ, ты же не этого наверное хочешь ?
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32667797
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vovaka
в общем потом попробовал еще пару раз - table scan пропало ... теперь еще непонятней стало :)
...
так полезен ли будет кластерный индекс ?

Так что ж непонятного ? Я так понимаю, это он и есть - вожделенный оптимальный план.
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32667803
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ASCRUS
В скрипте подзапроса в WHERE стоит "prefix = e164prefix". Так что не едино. Во вторых ASA после переноса запроса в FROM уведет его в дерево главного плана, убрав Subquery, что уже прибавит скорости немало.

Не понял. Коррелированный ? или нет ? все равно не ясно. Не факт, что e164prefix - поле из внешнего запроса - квалификатора таблицы-то нет. Перенос же в главное дерево может только замедлить, впрочем, надо сначала разобраться, коррелированный подзапрос или нет.
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32667807
_Dog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vovaka
в общем потом попробовал еще пару раз - table scan пропало ... теперь еще непонятней стало :)


может АСА закешировала запрос?
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32667823
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vovaka
Как то я в плане запроса не вижу табличек globalprefixgroup и globalprefix. Или это уже план на другой запрос ? Просто хочется увидеть сам запрос и план на него.

По плану запроса можно сказать, что он неэффективен, так как по нему оптимизатор сначала сканирует по индексу подходящие условию записи, и считывая их значения с таблицы начинает строить хэш-таблицу по полям e164prefix, minuteprice и currencyrate, аггрегируя по ним нужные поля найденных записей. Далее он запихивает результат во временную таблицу для проведения сортировки. Наличие хэша говорит, что оптимизатор не нашел подходящего индекса, а наличие времянки говорит, что самих групп возвращается много и не хватает кэша памяти ASA для их размещения. Так что еще раз хочу сказать, что нужно пока забыть про индексы и более удачно переписать запрос, добившись того, чтобы в нем не было использования хэш алгоритма группировки (он хорош, только при условии малого кол-ва групп).

авторНе понял. Коррелированный ? или нет ? все равно не ясно. Не факт, что e164prefix - поле из внешнего запроса - квалификатора таблицы-то нет. Перенос же в главное дерево может только замедлить, впрочем, надо сначала разобраться, коррелированный подзапрос или нет.
Вся хитрость в том, что ASA != ASE почти во всем:
1. Квалификатор таблицы для указания поля связи в этом подзапросе не нужен, если таблицы подзапроса не имеют такого же поля. Хотя правильней его писать, чтобы вот потом не возникало таких споров.
2. Запрос явно является коррелированным, так как связывается по полю e164prefix с основным запросом, а так как он аггрегированный, то ASA потребовала бы включить его в группировку, что и сделано в запросе.
3. Перенос в главное дерево, т.е. избавление от Subquery всегда увеличивает скорость работы подзапроса в ASA, только при условии, если правильно переносить :) Например в данном случае переносить запрос нужно в основной запрос не через соединение INNER JOIN, а как LATERAL (прямое внутреннее соединение, которое позволяет внутри подзапроса ссылаться на поля главного запроса, но при этом алгоритм его выполнения эффективнее, чем работа с Subquery).

авторТак что ж непонятного ? Я так понимаю, это он и есть - вожделенный оптимальный план.
Как я уже и говорил выше, ничего хорошего в этом плане нет, учитывая размеры таблицы. Хэш-таблицы ASA начинает использовать не от хорошей жизни, а от вынужденной необходимости хоть как то обработать огромный массив записей.

авторможет АСА закешировала запрос?
Кэш не влияет на построение плана запроса. В данном случае правильный ответ будет из фразы:
авторв общем потом попробовал еще пару раз - table scan пропало ... теперь еще непонятней стало :)
а если вспомнить, что в ASA обучающийся эвристический анализатор, который после выполнения каждого запроса сравнивает полученные результаты с предполагаемыми, корректирует статистику по полям таблицы и индексов и начинает вести рэйтинг планов запросов, то этим скорее всего и обьясняется пропажа TableScan-а. Ну еще как вариант - это изменение условий запроса, которые привели к тому, что в выборках стала участвовать не сильно много записей.
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32668157
Фотография Vovaka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в общем вот запрос
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
select
(select g.name as lang from tel.globalprefixgroup g, tel.globalprefix p where
g.id = prefixgroupid and prefix = e164prefix and prefixgroupsetid =  6 ) lang, 
e164prefix as _e164prefix, minuteprice/currencyrate as minuteprice, count(*), 
sum(billingduration)/ 60  as sbd, sum(callprice/currencyrate) as _sum, sum(callduration)/ 60  as scd 
from voip.cdr_billing where datetime between '2004-08-25' and '2004-08-26' and accounttype in ( 2 ,  3 ,  4 ,  8 ) and accountid =  543  
group by _e164prefix, minuteprice
order by  2 

индекс в таблице только один (accountid, accounttype, datetime)
вот план
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
( Plan [ Total Cost Estimate:  16 . 86433  ] 
  ( WorkTable
    ( Sort
      ( HashGroupBy
        ( NestedLoopsJoin[ TRUE ]
          ( InList )
          ( IndexScan cdr_billing voip_cdr_billing_accountid_accounttype_datetime )
        )
      )
    )
  )
)
( SubQ  1  [ Total Cost Estimate: . 0128049703  ] 
  ( NestedLoopsJoin[ TRUE ]
    ( IndexScan ( GlobalPrefix p ) PrefixName )
    ( IndexScan ( GlobalPrefixGroup g ) GlobalPrefixGroup[ g.PrefixGroupSetID =   6  :  3 . 06243673 % Statistics ] )
  )
)

пробовал сделать подзапрос через join - выигрыша нет
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
( Plan [ Total Cost Estimate:  19 . 44261881  ] 
  ( WorkTable
    ( Sort
      ( HashGroupBy
        ( Left Outer *HashJoin
          ( HashFilter 
            ( NestedLoopsJoin[ TRUE ]
              ( InList )
              ( IndexScan cdr_billing voip_cdr_billing_accountid_accounttype_datetime )
            )
          )
          ( NestedLoopsJoin[ TRUE ]
            ( IndexScan ( GlobalPrefixGroup g ) GlobalPrefixGroupSet )
            ( IndexScan ( GlobalPrefix p ) GlobalPrefixGroup[ hash( p.Prefix ) in hashmap( cdr_billing.e164prefix ) : . 007117643 % Guess ] )
          )
        )
      )
    )
  )
)
через lateral не пробовал, это должно и на 7 и на 8 работать...

а вот как избавиться от хэшей ? результат выборки, в зависимости от периода может достигать сотен тысяч записей, в данном случае за сутки до десятков тысяч, после группировки остается максимум сотни две ...
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32668231
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если LATERAL пользоваться нельзя, то лучше тогда оставить как есть в subquery. Насчет оптимизации главного запроса: можно попробовать группы скинуть во времянку и поэксперементировать с соединениями. Тогда вполне возможно можно будет сделать составной индекс, первыми полями которого идут поля группировки, а потом поля фильтра.
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32668516
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ASCRUS

Вся хитрость в том, что ASA != ASE почти во всем:


В планах запросов он точно !=. Я так понял тот план, что это просто выполнение группировки.


ASCRUS
1. Квалификатор таблицы для указания поля связи в этом подзапросе не нужен, если таблицы подзапроса не имеют такого же поля. Хотя правильней его писать, чтобы вот потом не возникало таких споров.


В ASE тоже не нужен. Да и вообще, это ANSI -стандарт требует.
Так что не так уж и !=.

ASCRUS
2. Запрос явно является коррелированным, так как связывается по полю e164prefix с основным запросом, а так как он аггрегированный, то ASA потребовала бы включить его в группировку, что и сделано в запросе.


Там это само поле e164prefix тоже есть в списке вывода. Есть или нет e164prefix в двух таблицах подзапроса - мы не знаем. Да и вообще, что гадать ? Пусть товарищь пришлет скрипты на таблицы и запрос, и план его.
Тогда можно о чем-то говорить.

ASCRUS
3. Перенос в главное дерево, т.е. избавление от Subquery всегда увеличивает скорость работы подзапроса в ASA, только при условии, если правильно переносить :) Например в данном случае переносить запрос нужно в основной запрос не через соединение INNER JOIN, а как LATERAL (прямое внутреннее соединение, которое позволяет внутри подзапроса ссылаться на поля главного запроса, но при этом алгоритм его выполнения эффективнее, чем работа с Subquery).


Впервые слышу про такого зверя.
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32668565
Фотография Vovaka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот скрипты, но этот подзапрос для выдергивания имени особенно не требует времени, т.к. результат группировки содержит небольшое кол-во строк

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
create table "Tel".GlobalPrefixGroup (
	ID                int primary key default autoincrement,
	PrefixGroupSetID  int references "Tel".GlobalPrefixGroupSet(ID) on update cascade on delete cascade,
        Name              char( 64 )
); 

create table "Tel".GlobalPrefix (
	ID                int primary key default autoincrement,
	PrefixGroupID     int references "Tel".GlobalPrefixGroup(ID) on update cascade on delete cascade,
        Prefix            char( 16 )
); 

а LATERAL появился только в ASA 9
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32668599
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ты думаешь, сервер сначала выполняет группировку, а потом подзапрос ? Далеко не факт, что так будет. Обычно происходит как раз наоборот. Что в твоем случае будет достаточно плохо.

Кстати, если это поле, которое подзапрос выводит, одно на запрос, то можно его в переменную выбрать.
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32668603
Фотография Vovaka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
используя LATERAL получаетсядаже чуть хуже
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
select
e164prefix as _e164prefix, minuteprice/currencyrate as minuteprice, count(*), 
sum(billingduration)/ 60  as sbd, sum(callprice/currencyrate) as _sum, sum(callduration)/ 60  as scd 
from voip.cdr_billing, 
LATERAL (select g.name as lang from tel.globalprefixgroup g, tel.globalprefix p where g.id = prefixgroupid and prefix = e164prefix and prefixgroupsetid =  6 ) lang
where datetime between '2004-08-25' and '2004-08-26' and accounttype in ( 2 ,  3 ,  4 ,  8 ) and accountid =  33  
group by _e164prefix, minuteprice
order by  2 

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
( Plan [ Total Cost Estimate:  22 . 06509988  ] 
  ( WorkTable
    ( Sort
      ( HashGroupBy
        ( HashJoin*
          ( NestedLoopsJoin[ TRUE ]
            ( IndexScan ( GlobalPrefixGroup g ) GlobalPrefixGroupSet )
            ( IndexScan ( GlobalPrefix p ) GlobalPrefixGroup )
          )
          ( NestedLoopsJoin[ TRUE ]
            ( InList )
            ( IndexScan cdr_billing voip_cdr_billing_accountid_accounttype_datetime )
          )
        )
      )
    )
  )
)

и всем огромное спасибо
p.s. а ASCRUS еще и отдельное за статью об индексах
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32668640
Linas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Index:
Код: plaintext
1.
create index test on voip.cdr_billing(accountid, datetime, e164prefix, minuteprice, currencyrate)

Query:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
select
(select first g.name as lang from tel.globalprefixgroup g, tel.globalprefix p where
g.id = prefixgroupid and prefix = e164prefix and prefixgroupsetid =  6 ) lang, 
e164prefix as _e164prefix, minuteprice/currencyrate as minuteprice, count(*), 
sum(billingduration)/ 60  as sbd, sum(callprice/currencyrate) as _sum, sum(callduration)/ 60  as scd 
from voip.cdr_billing where datetime between '2004-08-01' and '2004-08-02' and accounttype in ( 2 ,  3 ,  4 ,  8 ) and accountid =  33  
group by cdr_billing.e164prefix, cdr_billing.minuteprice, cdr_billing.currencyrate
order by cdr_billing.e164prefix

HTH, Linas
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32668830
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Linas
Так как:
Код: plaintext
datetime between '2004-08-01' and '2004-08-02' 
то могу 100% сказать что при навязывании Вашего индекса будет на запрос ASA покажет для IndexSeek:
Код: plaintext
1.
2.
3.
4.
accountid = value
value <= datetime >= value
e164prefix *
minuteprice *
currencyrate *
а если FORCE не указывать, то она его вообще использовать не будет, так как накладно это получается.
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32669008
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати если выборка аналитического характера и может строиться с некоторым опозданием во времени, то стоит подумать о введении табличек, хранящих аггрегаты и автоматом рассчитывающихся в определенные промежутки времени (фактически аналог материализованных представлений).
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32669186
Linas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Da, nepodumal pro interval. Togda problema. Mozno poprobovat tak:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
create index test1 on voip.cdr_billing(accountid, e164prefix, minuteprice, currencyrate);

select
(select first g.name as lang from tel.globalprefixgroup g, tel.globalprefix p where
g.id = prefixgroupid and prefix = e164prefix and prefixgroupsetid =  6 ) lang, 
e164prefix as _e164prefix, minuteprice/currencyrate as minuteprice, count(*), 
sum(billingduration)/ 60  as sbd, sum(callprice/currencyrate) as _sum, sum(callduration)/ 60  as scd 
from voip.cdr_billing where datetime between '2004-08-01' and '2004-08-02' and accounttype in ( 2 ,  3 ,  4 ,  8 ) and accountid =  33  
group by cdr_billing.e164prefix, cdr_billing.minuteprice, cdr_billing.currencyrate
order by cdr_billing.e164prefix
ili tak:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
create index test2 on voip.cdr_billing(accountid, datetime, e164prefix, minuteprice, currencyrate);

SELECT 
  (select first g.name as lang from tel.globalprefixgroup g, tel.globalprefix p where
            g.id = prefixgroupid and prefix = e164prefix and prefixgroupsetid =  6 ) lang, 
   e164prefix as _e164prefix, minuteprice, 
   SUM(CNT), SUM(sbd) AS sbd, SUM(_sum) AS _sum, SUM(SCD) AS scd
FROM (select
        e164prefix, minuteprice/currencyrate as minuteprice, count(*) AS CNT, 
        sum(billingduration)/ 60  as sbd, sum(callprice/currencyrate) as _sum, sum(callduration)/ 60  as scd 
      from voip.cdr_billing where datetime between '2004-08-01' and '2004-08-02' and accounttype in ( 2 ,  3 ,  4 ,  8 ) and accountid =  33  
      group by CDR_BILLING.DATETIME, cdr_billing.e164prefix, cdr_billing.minuteprice, cdr_billing.currencyrate
) AS DERIVED
GROUP BY DERIVED.e164prefix, DERIVED.minuteprice
order by DERIVED.e164prefix
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32669192
A
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Или подождать ASA Jasper - там будут Materialized views.
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32730952
bars62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Рассматривая original QUERY я бы сказал что ету проблему надо решать несколько иначе. Учитывая то что ты делаеш выборку всего за 2 дня то максимальное колличество выбранных рекордов у тебя должно быть дге-то в пределах 800000 - ето не так уж много.
Поэтому основное решение должно быть в разбивке твоего одного QUERY на несколько этапов:

1. Создание временной таблицы:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
CREATE TABLE #billing_temp (
lang        char(64)     NULL,
_e164prefix char(16) NOT NULL,
minuteprice double   NOT NULL,
total_count integer      NULL,
sbd         double   NOT NULL,
_sum        double   NOT NULL,
scd         double   NOT NULL);
Код: plaintext
1.
CREATE INDEX billing_e164prefix_temp on #billing_temp (_e164prefix, minuteprice);


2. Основная выборка во времменую таблицу:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
INSERT INTO #billing_temp (lang, _e164prefix, minuteprice, total_count, sbd, _sum, scd)
SELECT NULL, 
       e164prefix, 
       minuteprice/currencyrate, 
       NULL, 
       sum(billingduration)/60, 
       sum(callprice/currencyrate), 
       sum(callduration)/60
FROM   voip.cdr_billing
WHERE  accountid = 543 
and    accounttype in (2, 3, 4, 8)
and    datetime >= '2004-08-25' 
and    datetime <= '2004-08-26'

Я бы заменил CLAUSE "datetime between '2004-08-25' and '2004-08-26'" на более простое выражение - SYBASE это выполняет быстрее.
Этот SELECT вернёт больше рекордов зато индексы voip_cdr_billing_accountid_accounttype и voip_cdr_billing_datetime
будут работать и ты не будеш гонять JOIN (или CORRELETED SUBQUERY) на остальные 2 таблицы (tel.globalprefixgroup i tel.globalprefix) на все миллионы рекордов.

3. Чистка

Код: plaintext
1.
2.
3.
4.
5.
6.
DELETE FROM #billing_temp
WHERE NOT EXISTS (SELECT *
                  FROM tel.globalprefixgroup g, tel.globalprefix p
                  WHERE p.prefixgroupid    = g.id
                  AND   g.prefixgroupsetid = 6
                  AND   p.prefix           = #billing_temp._e164prefix)

4. Update

Код: plaintext
1.
2.
3.
4.
5.
6.
UPDATE #billing_temp
SET lang = (SELECT g.name
            FROM tel.globalprefixgroup g, tel.globalprefix p
            WHERE p.prefixgroupid    = g.id
            AND   g.prefixgroupsetid = 6
            AND   p.prefix           = #billing_temp._e164prefix)
Код: plaintext
1.
2.
3.
4.
5.
UPDATE #billing_temp
SET total_count = (SELECT count(*)
                   FROM #billing_temp a
                   WHERE a._e164prefix = #billing_temp._e164prefix
                   AND   a.minuteprice = #billing_temp.minuteprice)


В данном случае даже не надо делать GROUP BY

5. Final SELECT

Код: plaintext
1.
2.
3.
SELECT *
FROM #billing_temp
ORDER BY 2
Код: plaintext
1.
DROP TABLE #billing_temp


Вся ета структура может быть более громоздкая зато оптимизация будет лучше и все индексы будут работать.

_________________________________
Евгений
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32730953
bars62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Только сейчас обратил внимание что у тебя ASA а не ASЕ. В этом случае временную таблицу надо создавать в схеме voip и не обязательно использовать #.
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32747367
Dmitriy Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мои 2 цента (копейки)...

Судя по Вашему запросу, независимо от того, насколько велика таблица, диапазон дата от ... до, по всей видимости - 1 месяц в 99% случаев. Это и есть то условие, которое позволит сделать Вашу таблицу "маленькой", ибо время (т.е. поле "дата транзакции") - как раз и есть та "ось" по которой ваша таблица растет.

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

Из того что могу предложить сам (пальцем в небо) - индекс по дате, потом по тому, что у Вас стоит в GROUP BY. Тип счета на мой взгляд не надо, он должен сам ручками перебрать.

Честно, не знаю как он group by обрабатывает, так что может ничего и не выйдет. На ваш план я еще не поглядел толком - дома гляну.
...
Рейтинг: 0 / 0
ASA9.0.1 Помогите с оптимальными индексами на большой таблице
    #32747368
Dmitriy Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
... замена BETWEEN ни к чему не приведет. В ASA это 100% эквивалент X >=A AND X <= B
...
Рейтинг: 0 / 0
39 сообщений из 39, показаны все 2 страниц
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / ASA9.0.1 Помогите с оптимальными индексами на большой таблице
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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