|
28.10.2006, 16:01 | #1 |
Участник
|
aEremenko: Порядок полей в индексе для DAX 3.0
Источник: http://blogs.msdn.com/aeremenk/archi...14/825247.aspx
============== Все время забываю записать, что есть параметр для конфигурационной утилиты, позволяющий допускать изменение полей в индексе. Это актуально при тюнинге производительности системы, когда необходимо управлять порядком системного поля DATAAREAID в индексе. Не секрет, что перемещение данного поля в конец индекса может дать ощутимый прирост в производительности системы при небольшом количестве компаний. Параметр должен быть указан в поле Advanced конфигурационной утилиты: -internal=CROSSCOMPANY Параметр позволяет добавлять вручную поле DATAAREAID в индекс, соответственно, можно самому определять порядок. Параметр не влияет на прочие индексы. Применять осторожно, тестировать в любом случае. Есть ли клиенты, использующие данный параметр длительное время? Есть, я знаю как минимум одного, но не в России. Источник: http://blogs.msdn.com/aeremenk/archi...14/825247.aspx |
|
|
За это сообщение автора поблагодарили: alex55 (1). |
07.11.2006, 10:26 | #2 |
Administrator
|
Странно. Не нашел этот параметр в списке
В любом случае, конфигурационная утилита, по-моему, не лучшее место для указания такого рода параметров. Что будет, если одному из клиентов такой параметр в утилите забудут прописать? Есть еще один способ достижения точно такого же эффекта. Для этого надо изменить значение параметра INDEX в таблице SQLSYSTEMVARIABLES. Вот описание значений этого параметра: Цитата:
System Variable
INDEX Values Value ‘0’ for indexes not supported, or one or more of the other options added together: 0 : Not supporting indexes. 1 : Default flag for enabling index support. 2 : Index generation reversed (i.e. most important index generated last). 4 : Allow DESC on index components in CREATE INDEX statement. 8 : Add table qualifiers to index names. 16: Put the DATAAREAID (the “company field) last in indexes, and do not put the field in the ORDER BY clause at all. 32: This session is using “RECIDs per company”, which consequently will add the DATAAREAID to the built-in RecId-index. 64: This session is using “RECIDs per company+table”
__________________
Not registered yet? Register here! Have comments, questions, suggestions or anything else regarding our web site? Don't hesitate, send them to me Последний раз редактировалось Maxim Gorbunov; 07.11.2006 в 10:43. |
|
|
За это сообщение автора поблагодарили: mazzy (5), Garic (2), belugin (8), Logger (2), alex55 (1), SRF (2). |
22.11.2006, 12:39 | #3 |
Участник
|
|
|
22.11.2006, 13:13 | #4 |
Злыдни
|
Эта настройка производится в таблице SQLSYSTEMVARIABLE для строки INDEX. Внимательней читайте, пожалуйста, сообщения.
__________________
люди...считают, что если техника не ломается, то ее не нужно ремонтировать. Инженеры считают, что если она не ломается, то нуждается в совершенствовании. |
|
18.06.2009, 08:27 | #5 |
Участник
|
Думаю, что наверное Вы уже знаете, про данный параметр, но кто-то может и не знать.
Если заглянуть в класс SQLDataBaseInit, то в определении класса можно увидеть макрос #define.transidsPerCompany(256), откуда можно сделать предположение, это значение отвечает за генерацию TransactionId в разрезе компании(проверил на DAX 4.0, так оно и оказалось ), про 256 можно сказать так : Цитата:
256: This session is using “TransactionsID per company”
Цитата:
4 : Allow DESC on index components
in CREATE INDEX statement. Выскажу предположение, что это может быть как-то связано с тем, что до версии Oracle 8i ключевое слово DESC игнорировалось в инструкции CREATE INDEX(т.е. возможно, что нужны еще какие-то доп. условия, чтобы параметр desc подставлялся в инструкцию create index) Оффтоп : Пока смотрел как используется значение 4, обнаружил интересный момент(багофича). В AX 3.0 и AX 4.0 есть класс SqlscanSQLIndex, который используется при проверки\синхронизации таблиц(Администрирование\Периодические операции\SQL Администрирование). У данного класса есть метод isDescendingOrder, который по логике вещей должен определять порядок сортировки поля в индексе, однако он всегда возвращает false, несмотря на то, что использует массив descendingOrder, просто разработчики видимо забыли что, его нужно тоже заполнять Причем не заполняется он ни для Oracle, ни для MS SQL Server. Более того, для MS SQL Server - для определения структуры индекса используется хранимая процедура sp_helpindex, которая в случае если поле в индексе имеет порядок сортировки desc возвращает после него "(-)", что тоже никак не учтено . Т.е. к примеру - у вас есть таблица, у нее есть индекс, содержащий поле field1. Теперь если вы не посредственно на SQL Server для данного поля в индексе выставите сортировку DESC, а потом запустите проверку\синхронизацию таблицы, то в отчете будет выведено, что поле индекса в БД имеет имя field1(-), а в AOT field1, хотя изменился только порядок сортировки. Ниже приведен код для DAX 4.0, исправляющий данную ситуацию(тестировал на SQL 2005), изменения нужно внести в метод sqlServerGetIndexInfo класса SqlscanSQLIndex: X++: private void sqlServerGetIndexInfo() { Statement stmt = con.createStatement(); Statement stmt1 = con.createStatement(); ResultSet resultSet; str columns; str columnToken; str realIndexes[ #DEFINE.MAX_INDEX_PER_TABLE ]; int nbrRealIndexes = 0; str queryString; str result2; str indexName; int len, columnNo, i; int strCount; boolean sysTraceActive = xSession::getSysTraceActive(); SqlStatementExecutePermission ssep; //srf --> boolean isDescOrder; str descToken = "(-)"; //srf <-- ; xSession::setSysTraceActive(true); queryString = 'SELECT name FROM sysindexes WHERE indid>0 AND indid<255 AND id=object_id(\'' + sQLIndexTable + '\')'+ ' AND INDEXPROPERTY(id, name, \'IsStatistics\') = 0'; //Assert executeQuery a Dangerous APi ssep = new SqlStatementExecutePermission ( queryString ); ssep.assert(); //BP Deviation Documented resultSet = stmt.executeQuery( queryString ); while (resultSet.next() ) { nbrRealIndexes++; realIndexes[nbrRealIndexes] = resultSet.getString( 1 ); } if (!nbrRealIndexes) return; //revert assert CodeAccessPermission::revertAssert(); queryString = '/*SP*/ exec sp_helpindex ' + sQLIndexTable; //Assert executeQuery a Dangerous APi ssep = new SqlStatementExecutePermission ( queryString ); ssep.assert(); //BP Deviation Documented resultSet = stmt.executeQuery( queryString ); while( resultSet.next() ) { indexName = resultSet.getString( 1 ); for (i=1;i<=nbrRealIndexes;i++) { if (realIndexes[i] == indexName) break; } if (i<=nbrRealIndexes) /* not a statistics index */ { result2 = resultSet.getString( 2 ); this.completeIndex(); this.addIndex(indexName); isUnique[idxCnt] = (strscan(result2, 'unique', 0, strlen(result2)) ? true : false ); isCluster[idxCnt] = (strscan(result2, 'clustered', 0, strlen(result2)) ? true : false ); if (isCluster[idxCnt] && strscan(result2, 'nonclustered', 0, strlen(result2))) isCluster[idxCnt] = false; isPrimary[idxCnt] = (strscan(result2, 'primary key', 0, strlen(result2)) ? true : false ); columns = resultSet.getString( 3 ); len = strlen( columns ); strCount = 1; columnNo = 0; while( strCount <= len ) { columnToken = ''; //srf --> isDescOrder = false; //srf <-- while( strCount <= len && substr( columns, strCount, 1 ) != ',' && substr( columns, strCount, 1 ) != ' ' ) { columnToken += substr( columns, strCount, 1 ); strCount++; } //srf --> if (Global::strEndsWith(columnToken, descToken)) { isDescOrder = true; columnToken = substr(columnToken, 1, strlen(columnToken) - strlen(descToken)); } //srf <-- if( this.generalFieldHandling( columnToken, columnNo ) ) { fldCnt++; columnNo++; fieldNames[fldCnt] = columnToken; fieldNo[fldCnt] = columnNo; //srf --> descendingOrder[fldCnt] = isDescOrder; //srf <-- } while( strCount <= len && substr( columns, strCount, 1 ) == ',' || substr( columns, strCount, 1 ) == ' ' ) strCount++; } } } this.completeIndex(); xSession::setSysTraceActive(sysTraceActive); } Кстати, в AX 2009 - данный класс отсутсвует совсем, а проверка и синхронизация таблиц, была вынесена на уровень ядра. |
|
|
За это сообщение автора поблагодарили: mazzy (2), Logger (2). |
18.06.2009, 09:25 | #6 |
Участник
|
Я пробовал устанавливать параметр 16 для индексов (DATAAREA в конце индекса), но, честно говоря, не увидел никаких изменений в поведении системы. Кол-во блокировок осталось тем-же - в общем не нашел положительных моментов. На Оракле оставил как есть по дефолту.
|
|
22.11.2006, 13:21 | #7 |
Участник
|
Logger, насколько я понял, спрашивал, как после установки этого значения в INDEX в БД установить ниспадающий порядок сортировки у какого-то из индексов в АОТ?
|
|
22.11.2006, 14:24 | #8 |
Участник
|
|
|
22.11.2006, 15:31 | #9 |
Злыдни
|
Извините. Решил сам поиграть со значением для Index. Установил по максимуму в 383 и ... Никаких новых свойств не увидел. Будет ждать ответ от гуру
__________________
люди...считают, что если техника не ломается, то ее не нужно ремонтировать. Инженеры считают, что если она не ломается, то нуждается в совершенствовании. |
|
22.11.2006, 15:16 | #10 |
NavAx
|
Попробовал настройку. Переиндексировал табличку SalesLine.
Действительно DataAreaId встал теперь последним. Во всех индексах кроме TransIdIdx, странно - чем этот индекс особенный-то?
__________________
С уважением, Игорь Ласийчук. |
|
22.11.2006, 15:21 | #11 |
Участник
|
TransIdIdx выбран как PrimaryIndex для этой таблицы
|
|
22.11.2006, 15:43 | #12 |
NavAx
|
Цитата:
Получилось что если в salesLine есть записи только в одной компании, то TransIdIdx получается нормальным - с DataAreaId вконце. Видимо система ещё учитывает записи по компаниям.
__________________
С уважением, Игорь Ласийчук. |
|
22.11.2006, 15:24 | #13 |
NavAx
|
Синхронизирую PurchTable - Primary index = PurchIdx
Тем не менее, dataAreaId встаёт последним.
__________________
С уважением, Игорь Ласийчук. |
|
22.11.2006, 15:40 | #14 |
Злыдни
|
Аха. Через manage index проверил табличку Address:
- в индексах DataAreaId съехал в конец; - поменялся порядок индексов в таблице (?). Раньше индекс по RecId (DA + RI) был в конце, теперь влез между двумя другими индексами. Интересно почему.
__________________
люди...считают, что если техника не ломается, то ее не нужно ремонтировать. Инженеры считают, что если она не ломается, то нуждается в совершенствовании. |
|
22.11.2006, 17:10 | #15 |
Злыдни
|
Упс. Решил проверить значение 255. Синхронизация упала при невозможности создать индекс по recId. Пришлось восстанавливать базу. Хорошо, что в ней только справочники.
__________________
люди...считают, что если техника не ломается, то ее не нужно ремонтировать. Инженеры считают, что если она не ломается, то нуждается в совершенствовании. |
|
31.12.2010, 12:50 | #16 |
Участник
|
Цитата:
Сообщение от Blog bot
Источник: http://blogs.msdn.com/aeremenk/archi...14/825247.aspx
============== Параметр должен быть указан в поле Advanced конфигурационной утилиты: -internal=CROSSCOMPANY Параметр позволяет добавлять вручную поле DATAAREAID в индекс, соответственно, можно самому определять порядок. Параметр не влияет на прочие индексы. Источник: http://blogs.msdn.com/aeremenk/archi...14/825247.aspx Причем это очень полезная фича когда используется запрос по многим компаниям, например тут \Classes\LedgerJournalCheckPost\interCompanyTransferToCustPayment генерится такой запрос X++: select firstonly forceplaceholders crossCompany vendSettlement where vendSettlement.OffsetTransVoucher == ledgerJournalTrans.Voucher && vendSettlement.OffsetCompany == ledgerJournalTrans.Company join vendTrans where vendTrans.RecId == vendSettlement.TransRecId && vendTrans.AccountNum == vendSettlement.AccountNum && vendTrans.Invoice; \Data Dictionary\Tables\VendSettlement\Indexes\OffsetVoucherIdx с полями по dataareaId, OffsetTransVoucher - неоптимален. Причем чем больше компаний в базе тем сильнее эффект. Достаточно запихнуть dataareaId в конец и все в порядке. |
|
Теги |
ax2009, ax3.0, crosscompany, индекс, производительность |
|
|