28.05.2009, 13:01 | #1 |
Участник
|
Как работает индекс и кеш запросов?
Добрый день.
Возможно это уже обсуждалось, но полной информации я, к сожалению, не нашел :-( Выполняется аксаптовский код select sum(CostAmountPosted), sum(CostAmountAdjustment) from inventTrans where inventTrans.InventTransId == '03045451' && inventTrans.StatusIssue == StatusIssue::None && inventTrans.StatusReceipt == StatusReceipt::Purchased && inventTrans.InvoiceId == '90003347'; На профайлере SQL отлавливаю данный запрос. Получаю следующее exec sp_cursorprepexec @p1 output,@p2 output,N'@P1 varchar(1000),@P2 varchar(1000),@P3 int,@P4 int,@P5 varchar(1000)',N'SELECT SUM(A.COSTAMOUNTPOSTED),SUM(A.COSTAMOUNTADJUSTMENT) FROM INVENTTRANS A(INDEX(I_177STATUSITEMIDX)) WHERE ((DATAAREAID=@P1) AND ((((INVENTTRANSID=@P2) AND (STATUSISSUE=@P3)) AND (STATUSRECEIPT=@P4)) AND (INVOICEID=@P5))) OPTION(FAST 2)',@p5 output,@p6 output,@p7 output,'guk',' 03045451',0,1,' 90003347' Вопрос в следующем, откуда взялся хинт по индексу I_177STATUSITEMIDX? Насколько я понимаю индекс приходит уже с приложения (проверял через Query Analyzer без него - работает быстрее и индекс берется другой). Я так понимаю, аксапта где-то хранит у себя в кеше или еще где-то данный индекс. Где это можно посмотрет? Чем руководствуется Система, когда сюда его подцепляет (данный индекс неоптимален ( ) Заранее благодарю за помощь Версия аксапты AX3Sp3CU1, версия сервера БД SQL2005 SP2 x64, версия ОС - Win2003SP2 x64
__________________
Жить все веселей!.. AX3SP3CU1 |
|
28.05.2009, 13:06 | #2 |
Ищущий знания...
|
На сколько мне известно (могу и ошибаться) но запросы оптимизирует сама БД, т.е. подставляет индексы и т.п. Возможно в БД храниться какой то кэш об оптимальном выполнении Вашего запроса, и он берет тот план исполнения, которые считает оптимальным.
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
28.05.2009, 13:13 | #3 |
Участник
|
да, вы правы . Но в данном случае (если смотреть через профайлер) то запрос из Аксапты уже приходит с индексом! При запуске запроса без индекса через QA оптимизатор действительно подбирает оптимальный план. И следует отдать ему должное - по другому, более оптимальному, индексу
__________________
Жить все веселей!.. AX3SP3CU1 |
|
28.05.2009, 13:36 | #4 |
Ищущий знания...
|
Цитата:
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
28.05.2009, 14:09 | #5 |
Участник
|
Цитата:
Сообщение от Didukh84
Добрый день.
Возможно это уже обсуждалось, но полной информации я, к сожалению, не нашел :-( Выполняется аксаптовский код select sum(CostAmountPosted), sum(CostAmountAdjustment) from inventTrans where inventTrans.InventTransId == '03045451' && inventTrans.StatusIssue == StatusIssue::None && inventTrans.StatusReceipt == StatusReceipt::Purchased && inventTrans.InvoiceId == '90003347'; На профайлере SQL отлавливаю данный запрос. Получаю следующее exec sp_cursorprepexec @p1 output,@p2 output,N'@P1 varchar(1000),@P2 varchar(1000),@P3 int,@P4 int,@P5 varchar(1000)',N'SELECT SUM(A.COSTAMOUNTPOSTED),SUM(A.COSTAMOUNTADJUSTMENT) FROM INVENTTRANS A(INDEX(I_177STATUSITEMIDX)) WHERE ((DATAAREAID=@P1) AND ((((INVENTTRANSID=@P2) AND (STATUSISSUE=@P3)) AND (STATUSRECEIPT=@P4)) AND (INVOICEID=@P5))) OPTION(FAST 2)',@p5 output,@p6 output,@p7 output,'guk',' 03045451',0,1,' 90003347' Вопрос в следующем, откуда взялся хинт по индексу I_177STATUSITEMIDX? Насколько я понимаю индекс приходит уже с приложения (проверял через Query Analyzer без него - работает быстрее и индекс берется другой). Я так понимаю, аксапта где-то хранит у себя в кеше или еще где-то данный индекс. Где это можно посмотрет? Чем руководствуется Система, когда сюда его подцепляет (данный индекс неоптимален ( ) Заранее благодарю за помощь Версия аксапты AX3Sp3CU1, версия сервера БД SQL2005 SP2 x64, версия ОС - Win2003SP2 x64 X++: select sum(CostAmountPosted), sum(CostAmountAdjustment) from inventTrans where inventTrans.InventTransId == '03045451' && inventTrans.StatusIssue == StatusIssue::None && inventTrans.StatusReceipt == StatusReceipt::Purchased && inventTrans.InvoiceId == '90003347'; X++: select sum(CostAmountPosted), sum(CostAmountAdjustment) from inventTrans index hint StatusItemIdx where inventTrans.InventTransId == '03045451' && inventTrans.StatusIssue == StatusIssue::None && inventTrans.StatusReceipt == StatusReceipt::Purchased && inventTrans.InvoiceId == '90003347'; 1. Напишите джоб с данным запросом, и посмотрите, что уйдет на SQL(потом поставьте index hint TransIdIdx) 2. Вообще использование данного индекса в запросе (StatusItemIdx) навязывается самой аксаптой при помощи index hint(если функционал дорабатывался советую поискать подобный запрос и убрать hint должно стать лучше), однако если я не ошибаюсь в 4 в настройках АОС(на вкладке DataBase Tuning есть 'Allow Index Hints in queries' и если он установлен, то будет использоваться index, который навязан AX, а не тот, который СУБД посчитает лучшим). Посмотрите есть ли у вас подобный параметр(к сожалению тройки под рукой нет) и установлен ли он? (P.S. С даным параметром нужно быть придельно аккуратным) Последний раз редактировалось SRF; 28.05.2009 в 14:11. Причина: Опечатки |
|
28.05.2009, 14:40 | #6 |
Axapta Retail User
|
Цитата:
Сообщение от SRF
А вы уверены, что в AX именно такой код выполняется?
X++: select sum(CostAmountPosted), sum(CostAmountAdjustment) from inventTrans where inventTrans.InventTransId == '03045451' && inventTrans.StatusIssue == StatusIssue::None && inventTrans.StatusReceipt == StatusReceipt::Purchased && inventTrans.InvoiceId == '90003347'; В 3-шке параметра 'Allow Index Hints in queries' нет. |
|
28.05.2009, 14:48 | #7 |
----------------
|
рекомендую к прочтению
http://axapta.mazzy.ru/lib/indexhints/ |
|
28.05.2009, 15:02 | #8 |
Участник
|
Это ядро Аксапты, начиная с какого-то из KR-ов, вставляет собственные хинты.
Помимо отключения из конфигурации, можно для этого запроса просто добавить сортировку по полю InventTransId - в моем случае, на сервер уходит такой запрос X++: SELECT SUM(A.COSTAMOUNTPOSTED),SUM(A.COSTAMOUNTADJUSTMENT) FROM INVENTTRANS A WHERE ((DATAAREAID=?) AND ((((INVENTTRANSID=?) AND (STATUSISSUE=?)) AND (STATUSRECEIPT=?)) AND (INVOICEID=?))) OPTION(FAST 2)
__________________
Axapta v.3.0 sp5 kr2 |
|
28.05.2009, 15:23 | #9 |
Участник
|
Цитата:
Сообщение от SRF
А вы уверены, что в AX именно такой код выполняется?
X++: select sum(CostAmountPosted), sum(CostAmountAdjustment) from inventTrans where inventTrans.InventTransId == '03045451' && inventTrans.StatusIssue == StatusIssue::None && inventTrans.StatusReceipt == StatusReceipt::Purchased && inventTrans.InvoiceId == '90003347'; X++: select sum(CostAmountPosted), sum(CostAmountAdjustment) from inventTrans index hint StatusItemIdx where inventTrans.InventTransId == '03045451' && inventTrans.StatusIssue == StatusIssue::None && inventTrans.StatusReceipt == StatusReceipt::Purchased && inventTrans.InvoiceId == '90003347'; Цитата:
P.S. даже и хинта не нужно: просто index TransIdIdx хватило ;-)
__________________
Жить все веселей!.. AX3SP3CU1 |
|
28.05.2009, 15:31 | #10 |
Участник
|
Цитата:
Сообщение от ViV
Попроовала у себя - аксапта тоже выдала запрос "SELECT SUM(A.COSTAMOUNTPOSTED),SUM(A.COSTAMOUNTADJUSTMENT) FROM INVENTTRANS A(INDEX(I_177INVENTTRANSIDSTATUSR20002))" подставив откуда то (???) свой индекс хинт. Замечала подобное поведение и на других запросах.
В 3-шке параметра 'Allow Index Hints in queries' нет. X++: qBd.addSortIndex(indexnum(LedgerTrans, BondBatchIdx_RU)); X++: qbd.indexIsHint(true);
__________________
Жить все веселей!.. AX3SP3CU1 |
|
28.05.2009, 15:34 | #11 |
Участник
|
Цитата:
Сообщение от Wamr
рекомендую к прочтению
http://axapta.mazzy.ru/lib/indexhints/
__________________
Жить все веселей!.. AX3SP3CU1 |
|
28.05.2009, 15:35 | #12 |
Axapta Retail User
|
|
|
28.05.2009, 18:30 | #13 |
Модератор
|
Цитата:
__________________
-ТСЯ или -ТЬСЯ ? |
|
29.05.2009, 07:22 | #14 |
Участник
|
Директива index добавляет сортировку по полям индекса и как написал AndyD (поскольку добавилась сортировка) у вас план запроса должен стать(так ли это?) :
Цитата:
X++: SELECT SUM(A.COSTAMOUNTPOSTED),SUM(A.COSTAMOUNTADJUSTMENT) FROM INVENTTRANS A (INDEX(I_177TRANSIDIDX)) WHERE ((DATAAREAID=?) AND ((((INVENTTRANSID=?) AND (STATUSISSUE=?)) AND (STATUSRECEIPT=?)) AND (INVOICEID=?))) OPTION(FAST 2) P.S. Кстати в стандарной AX запросы вида X++: select sum(CostAmountPosted) from InventTrans where InventTrans.InventTransId == ... |
|
29.05.2009, 09:10 | #15 |
Участник
|
С KR поведение ядра по добавлению хинтов отличается от "чистой" Axapat'ы (без KR)
Без KR добавление ORDER BY не имеет эффекта. Наличие же INDEX ВСЕГДА отключает хинты ядра. Причем, даже если самого индекса и не существует в базе (отключен конф. ключ). И здесь так же есть различие в поведении с KR. Без KR в order by запроса всегда добавляются поля из индекса (для неагрегированного запроса). C KR - только если индекс не отключен в конфигурации. Так что, с KR можно создать для таблицы фейковый индекс и использовать его для критических запросов А вообще, выбор того или иного индекса зависит от количества полей, входящих в предложение WHERE, а так же от того, сколько этих полей входит в различные индексы (естественно, если не указывать index hint). Алгоритм, примерно, следующий:
Что заметил - соответствие полей в ORDER BY какому-либо индексу и наличие этих полей в предложении WHERE в некоторых случаях отключает хинты. PS Я пишу KR, но проверял только на KR2 (dax 3.0 sp5 kr2). Предположение, что это правильно для всех KR - надо проверять Без KR проверял на Axapta 3.0 sp3 cu1
__________________
Axapta v.3.0 sp5 kr2 |
|
|
За это сообщение автора поблагодарили: mazzy (2), dn (1), raz (13), ZVV (2), lev (1), SRF (1). |
01.06.2009, 10:22 | #16 |
Ищущий знания...
|
Цитата:
Сообщение от AndyD
...
Алгоритм, примерно, следующий:
Что заметил - соответствие полей в ORDER BY какому-либо индексу и наличие этих полей в предложении WHERE в некоторых случаях отключает хинты. PS Я пишу KR, но проверял только на KR2 (dax 3.0 sp5 kr2). Предположение, что это правильно для всех KR - надо проверять Без KR проверял на Axapta 3.0 sp3 cu1
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
01.06.2009, 12:41 | #17 |
Участник
|
Цитата:
Сообщение от SRF
Директива index добавляет сортировку по полям индекса и как написал AndyD (поскольку добавилась сортировка) у вас план запроса должен стать(так ли это?) :
В случае же c index hint TransIdIdx план запроса должен стать X++: SELECT SUM(A.COSTAMOUNTPOSTED),SUM(A.COSTAMOUNTADJUSTMENT) FROM INVENTTRANS A (INDEX(I_177TRANSIDIDX)) WHERE ((DATAAREAID=?) AND ((((INVENTTRANSID=?) AND (STATUSISSUE=?)) AND (STATUSRECEIPT=?)) AND (INVOICEID=?))) OPTION(FAST 2) Цитата:
в данном случае если бы выбрался данный индексе этой темы и не было бы ;-)
__________________
Жить все веселей!.. AX3SP3CU1 |
|
01.06.2009, 13:03 | #18 |
Участник
|
Зайдите в аксапту, откройте AOT (Ctrl + D), на корне дерева(узел AOT) нажмите CTRL + F, или в контекстном меню выберите команду 'Найти', на вкладке 'Имя и позиция' в поле 'Содержащийся текст' - наберите 'sum(CostAmountAdjustment)'(без апострофов) и нажмите кнопку 'Поиск', если у вас в коде приложения есть подобные запросы, то в результате вы сможете увидеть все места откуда данный запрос генерируется.
Если таковой запрос имеется, то поставьте для него насильно X++: index hint TransIdIdx P.S. Конечно можно просто на InventTrans добавить индекс с полями InventTransId, StatusReceipt, StatusIssue и во все не искать данный запрос в коде. НО этот вариант наверное лучше использовать только в самом крайнем случае. Последний раз редактировалось SRF; 01.06.2009 в 13:14. Причина: ошибки |
|
01.06.2009, 13:56 | #19 |
Участник
|
Так я знал. Но все равно спасибо. На счет места в коде откуда генерится запрос - я знаю (через трассировку вышел ;-) ).
__________________
Жить все веселей!.. AX3SP3CU1 |
|
02.06.2009, 10:42 | #20 |
MCITP
|
По моим субъективным ощущениям - на Оракле примерно то же самое...
__________________
Zhirenkov Vitaly |
|
Теги |
hint, index, kernel rollup, полезное, ax3.0, kr (kernel rollup) |
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|