AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX Blogs
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 18.06.2009, 08:27   #5  
SRF is offline
SRF
Участник
MCBMSS
Axapta Retail User
 
376 / 562 (19) +++++++
Регистрация: 08.08.2007
Записей в блоге: 1
Цитата:
Сообщение от Maxim Gorbunov Посмотреть сообщение
... За что отвечает значение 256, я не знаю.
Думаю, что наверное Вы уже знаете, про данный параметр, но кто-то может и не знать.

Если заглянуть в класс SQLDataBaseInit, то в определении класса можно увидеть макрос #define.transidsPerCompany(256), откуда можно сделать предположение, это значение отвечает за генерацию TransactionId в разрезе компании(проверил на DAX 4.0, так оно и оказалось ), про 256 можно сказать так :
Цитата:
256: This session is using “TransactionsID per company”
Посмотрел как используется значение 4 параметра INDEX в AX.
Цитата:
4 : Allow DESC on index components
in CREATE INDEX statement.
Как оказалось, используется это значение по-умолчанию только с СУБД Oracle, так же как и значение 128 (#define.indexOraStrFunctional(128)).
Выскажу предположение, что это может быть как-то связано с тем, что до версии 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);
}
После данного изменения при попытке проверки\синхронизации увидим вполне логичную надпись о том, что есть различия в порядке сортировки поля field1

Кстати, в AX 2009 - данный класс отсутсвует совсем, а проверка и синхронизация таблиц, была вынесена на уровень ядра.
За это сообщение автора поблагодарили: mazzy (2), Logger (2).
Теги
ax2009, ax3.0, crosscompany, индекс, производительность

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
aEremenko: Поддержка портала в DAX 4.0 на 64 бит Blog bot DAX Blogs 2 21.04.2008 18:13
aEremenko: Тестирование производительности в DAX 4.0 Blog bot DAX Blogs 0 12.03.2008 16:05
aEremenko: Как сопоставить пользователя DAX и сессию в Microsoft SQL? Blog bot DAX Blogs 2 04.10.2007 20:08
aEremenko: DAX 4.1 Blog bot DAX Blogs 0 04.03.2007 23:04
aEremenko: Порядок с драйверами от HP Blog bot DAX Blogs 0 28.10.2006 16:01

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 14:03.