Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / ASE + оптимизация запросов / 14 сообщений из 14, страница 1 из 1
28.07.2009, 14:43
    #36113479
Mikle83
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ASE + оптимизация запросов
Доброго всем времени суток!
Продолжаю бороться с АСЕ. Прошу помощи :)
Задача такая: есть таблица заказов (Card_Order), у каждого заказаесть идентификатор (ID)
Есть таблица статуса заказов (Card_StatusHistory), которая ссылается на таблицу заказов по полю Card_Order_ID, имеет идентификатор статуса заказа Status_ID и дату присвоения этого статуса (Doc_Date).
Т.е. в последнюю таблицу для каждого заказа заносится история изменения его статуса.

Стоит задача определить текущий статус каждого заказа. Для этого я написал такой запрос:

Select
count(*)
from Card_Order CO
join Card_StatusHistory CSH on CSH.Card_Order_ID = CO.ID_CRM
left join Card_StatusHistory CSHLater on (CSHLater.Card_Order_ID = CO.ID_CRM)
and (CSHLater.Doc_Date > CSH.Doc_Date)
where CSHLater.Card_Order_ID is null
plan "(use optgoal allrows_oltp)"


Индексы на всех нужных полях стоят.
План выполнения запроса:
|ROOT:EMIT Operator
|
| |SCALAR AGGREGATE Operator
| | Evaluate Ungrouped COUNT AGGREGATE.
| |
| | |NESTED LOOP JOIN Operator (Join Type: Left Outer Join)
| | |
| | | |NESTED LOOP JOIN Operator (Join Type: Inner Join)
| | | |
| | | | |SCAN Operator
| | | | | FROM TABLE
| | | | | Card_Order
| | | | | CO
| | | | | Index : CardOrder
| | | | | Forward Scan.
| | | | | Positioning at index start.
| | | | | Index contains all needed columns. Base table will not be read.
| | | | | Using I/O Size 2 Kbytes for index leaf pages.
| | | | | With LRU Buffer Replacement Strategy for index leaf pages.
| | | |
| | | | |SCAN Operator
| | | | | FROM TABLE
| | | | | Card_StatusHistory
| | | | | CSH
| | | | | Index : CSHDoc
| | | | | Forward Scan.
| | | | | Positioning by key.
| | | | | Index contains all needed columns. Base table will not be read.
| | | | | Keys are:
| | | | | Card_Order_ID ASC
| | | | | Using I/O Size 2 Kbytes for index leaf pages.
| | | | | With LRU Buffer Replacement Strategy for index leaf pages.
| | |
| | | |SCAN Operator
| | | | FROM TABLE
| | | | Card_StatusHistory
| | | | CSHLater
| | | | Index : CSHDoc
| | | | Forward Scan.
| | | | Positioning by key.
| | | | Index contains all needed columns. Base table will not be read.
| | | | Keys are:
| | | | Card_Order_ID ASC
| | | | Doc_Date DESC
| | | | Using I/O Size 2 Kbytes for index leaf pages.
| | | | With LRU Buffer Replacement Strategy for index leaf pages.



Вопрос к гуру Сайбеза - есть возможность какими-то доп. средствами оптимизировать данные запрос? (вариант с тригером на таблице истории и полем Текущий_Статус в основной таблице мое начальство рассматривать наотрез не хочет - пугает слово триггер)

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

Заранее спасибо
...
Рейтинг: 0 / 0
28.07.2009, 15:39
    #36113681
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ASE + оптимизация запросов
Mikle83 пишет:

> *Select
> count(*)
> from Card_Order CO
> join Card_StatusHistory CSH on CSH.Card_Order_ID = CO.ID_CRM
> left join Card_StatusHistory CSHLater on (CSHLater.Card_Order_ID =
> CO.ID_CRM)
> and (CSHLater.Doc_Date > CSH.Doc_Date)
> where CSHLater.Card_Order_ID is null

Этот запрос сам плохой. Надо вам последний статус - так так и напишите.
Выберите последний идентификатор статуса из истории статуса,
а потом статус с этим идентификатором.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
28.07.2009, 16:06
    #36113807
Mikle83
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ASE + оптимизация запросов
MasterZiv не совсем понял... Как последний статус?
Как его определить для каждой карты?
...
Рейтинг: 0 / 0
28.07.2009, 17:12
    #36114052
cherrex_Den
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ASE + оптимизация запросов
А что вы еще хотите оптимизировать? у вас везде читаются индексы и только индексы("Index contains all needed columns. Base table will not be read.")!
Что еще вы хотите оптимизировать?
...
Рейтинг: 0 / 0
28.07.2009, 17:17
    #36114070
Mikle83
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ASE + оптимизация запросов
cherrex_DenА что вы еще хотите оптимизировать? у вас везде читаются индексы и только индексы("Index contains all needed columns. Base table will not be read.")!
Что еще вы хотите оптимизировать?

Вот этого я и боялся :)
Т.е. получается, что для данного запроса это "потолок" по быстродействию...
...
Рейтинг: 0 / 0
28.07.2009, 17:24
    #36114101
cherrex_Den
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ASE + оптимизация запросов
для конкретного запроса - да! Но не для поставленной задачи. Смотрите что писал MasterZiv!
...
Рейтинг: 0 / 0
28.07.2009, 17:30
    #36114119
Mikle83
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ASE + оптимизация запросов
MasterZiv
Этот запрос сам плохой. Надо вам последний статус - так так и напишите.
Выберите последний идентификатор статуса из истории статуса,
а потом статус с этим идентификатором.


Здесь в том то и проблема что нельзя на идентификатор ориентироваться - только по дате можно контролить.

Т.е. вполне вероятна ситуация, что сначала прийдет статус допустим "2" с датой "2008-01-01"
а потом статус "1" с датой "2007-01-01" при этом идентификатор у последнего будет больше чем у предпоследнего...

Так вот данные затекают...
...
Рейтинг: 0 / 0
28.07.2009, 18:01
    #36114196
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ASE + оптимизация запросов
Mikle83 пишет:

> MasterZiv не совсем понял... Как последний статус?

Заказа статус.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
28.07.2009, 18:05
    #36114209
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ASE + оптимизация запросов
Mikle83 пишет:

> Здесь в том то и проблема что нельзя на идентификатор ориентироваться -
> только по дате можно контролить.

Ну ориентируйтесь на дату. Только странно это, что в одну и ту же дату
нельзя сменить несколько раз статус заказа ?

> Т.е. вполне вероятна ситуация, что сначала прийдет статус допустим "2" с
> датой "2008-01-01"
> а потом статус "1" с датой "2007-01-01" при этом идентификатор у
> последнего будет больше чем у предпоследнего...


Select *
from Card_Order CO
join Card_StatusHistory CSH on CSH.Card_Order_ID = CO.ID_CRM
and CSH.Doc_Date = ( select max ( CSHLater.Doc_Date )
from Card_StatusHistory CSHLater
where CSHLater.Card_Order_ID = CO.ID_CRM )


Что-то типа того.

Но это тоже не очешь производительный запрос.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
28.07.2009, 18:32
    #36114261
antand
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ASE + оптимизация запросов
Mikle83,

"вариант с тригером на таблице истории и полем Текущий_Статус в основной таблице мое начальство рассматривать наотрез не хочет - пугает слово триггер)"
Это и есть нормальный путь решения через триггер.
Только триггер должен быть на основной таблице, в основной таблице текущий статус, при изменении статуса писать историю в таблицу историй.
Тогда для определения текущего статуса таблица истории вообще не нужна, она нужна только для анализа истории по заказам.
...
Рейтинг: 0 / 0
28.07.2009, 19:04
    #36114325
antand
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ASE + оптимизация запросов
Кстати, писать в таблицу истории можно и не по триггеру(начальство успокоится).
Но поле текущий статус в основной конечно нужно.
...
Рейтинг: 0 / 0
28.07.2009, 20:32
    #36114410
Mikle83
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ASE + оптимизация запросов
antandКстати, писать в таблицу истории можно и не по триггеру(начальство успокоится).
Но поле текущий статус в основной конечно нужно.

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

Кстати, все-таки если у кого есть ссылки на доки по оптимизации запросов + на работу с планами запросов - киньте плиз...
...
Рейтинг: 0 / 0
29.07.2009, 10:09
    #36114842
Ggg_old
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ASE + оптимизация запросов
я за ХП. Прямой доступ в базу является злом по определению. И как следствие - различные неприятности и проблемки в поддержке базы. Лучше устранить причину проблемы а не тулить костыль в виде триггера.
...
Рейтинг: 0 / 0
29.07.2009, 11:17
    #36115029
Mikle83
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ASE + оптимизация запросов
ХП тоже не очень оптимальный вариант на мой взгляд...
Она отлично сработает при добавлении инфы по одной записи.

А если необходимо сразу записать статусы для 1000 заказов? Как работать? Я вижу два варианта:
1) Через временную таблицу
2) Гонять курсор и для каждой записи из датасета (ХП, насколько я знаю датасеты на вход принимать не умеет)

Ни тот ни другой вариант мне не нравятся - имхо п.2 долго работать будет, а п.1 - дополнительная брешь в обороне :)
...
Рейтинг: 0 / 0
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / ASE + оптимизация запросов / 14 сообщений из 14, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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