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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 20.01.2004, 13:12   #1  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Количество строк в Query
Существет ли какой-либо еще способ подсчитать количество строк в Query (несколько таблиц-источников), кроме тупого сканирования всех записей по while (qr.next)?

Дело в том, что это относительно медленный процесс. У меня получилось примерно 500 строк в секунду.

Если другого способа нет, то можно хотя бы ускорить процесс сканирования именно с целью подсчета количества строк?

PS: Объект SysQuery смотрел. Там подсчет именно через сканирование по while (qr.next)
Старый 20.01.2004, 13:45   #2  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
да, конечно.

SysQuery::countTotal(myQuery)

Спасибо за совет на этом форуме Евгению Глазову.
За это сообщение автора поблагодарили: evv (1).
Старый 20.01.2004, 14:16   #3  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Я же написал, что смотрел код объекта SysQuery. В частности SysQuery::CountPrim который собственно и выполняет расчет количества. Вот фрагмент его кода:

PHP код:
    ...
    while (
countQueryRun.next())
    {
        
common  countQueryRun.get(countQuery.dataSourceNo(1).table());
        
counter += common.recId;
        
loops++;
    }

    return [
counter,loops]; 
Т.е. это все тот же "тупой" перебор строк. Специально проверял время подсчета по SysQuery и явным циклом. Разницы не заметил Скорее даже прямой расчет предпочтительнее (меньше второстепенных операций)
Старый 20.01.2004, 14:31   #4  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Изначально опубликовано Владимир Максимов
Т.е. это все тот же "тупой" перебор строк.
Нет не тупой. Посмотрите как программно модифицируется query.
по сути дела в query остаются только условия, а вместо полей ставляется sum(recID).

А перебор нужен, если в query были группировки.

В общем, оттрасируйте и посмотртите тексты запросов.
Старый 20.01.2004, 14:45   #5  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 858 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
Count(RecId)
Есть такое условие в CountPrim
PHP код:
    if (countQuery.dataSourceCount() == 1)
        
qbds.addSelectionField(FieldNum(Common,recId),SelectionField::COUNT); 
Т.е. появляется интелект только когда в запросе 1 таблица

Могу предложить такой вариант:
PHP код:
static int prk_lineNumber2(FormDataSource fdsCommon tmpTable null)
{
    
Query                   query;
    
Query                   countQuery;
    
QueryRun                queryRun;
    
QueryBuildDataSource    qbds;
    
QueryBuildFieldList     qbfl;
    
int                     sourceNum;
    
int                     i;
    ;

    if (
fds.queryRun())
        
query   fds.queryRun().query();
    else
        
query   fds.query();

    
countQuery  = new Query(query);
    
sourceNum   countQuery.dataSourceCount();
    for ( 
1<= sourceNumi++ )
    {
        
qbds    countQuery.dataSourceNo(i);
        
qbfl    qbds.fields();
        
qbfl.clearFieldList();
        
qbfl.addField(FieldName2Id(qbds.table(),"RecId"), SelectionField::COUNT);
    }
    
queryRun    = new QueryRun(countQuery);

    
select TmpTable;

    if (
TmpTable)
        
queryRun.setCursor(TmpTable);


    
queryRun.next();

    return 
queryRun.getNo(1).RecId;

За это сообщение автора поблагодарили: alex55 (1).
Старый 20.01.2004, 14:56   #6  
Maxim Gorbunov is offline
Maxim Gorbunov
Administrator
Соотечественники
Лучший по профессии 2009
 
2,483 / 645 (26) +++++++
Регистрация: 27.11.2001
Адрес: Dubai, UAE
Да, Wamr совершенно прав, есть там такое место. Свои соображения по этому поводу изложил вот здесь: http://forum.mazzy.ru/index.php?show...indpost&p=1094 Не хочется заниматься копированием.

Wamr, Ваш метод также не лишен недостатка, связанного с тем, что в Query может быть GroupBy. Осмелюсь предположить, что он не работает (вернее, работает не совсем правильно), например, в форме InventOnhandItem (Запасы в наличии).
__________________
Not registered yet? Register here!
Have comments, questions, suggestions or anything else regarding our web site? Don't hesitate, send them to me
Старый 20.01.2004, 15:02   #7  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 858 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
Цитата:
Осмелюсь предположить, что он не работает (вернее, работает не совсем правильно), например, в форме InventOnhandItem (Запасы в наличии).
А он там и не используется

По поводу группировки
Осмелюсь предположить, что если в запросе есть Group by ItemId, то человека будет интересовать не количество записей попавших в группировку, а количество ItemId, т.е. записей после группировки. Вроде, ничего кроме перебора тут не поможет (countLoops).
За это сообщение автора поблагодарили: jeky (2).
Старый 20.01.2004, 15:11   #8  
Maxim Gorbunov is offline
Maxim Gorbunov
Administrator
Соотечественники
Лучший по профессии 2009
 
2,483 / 645 (26) +++++++
Регистрация: 27.11.2001
Адрес: Dubai, UAE
Ну, в общем-то так оно и есть. По ссылке я написал, как объединить countTotal и countLoops в один метод.
__________________
Not registered yet? Register here!
Have comments, questions, suggestions or anything else regarding our web site? Don't hesitate, send them to me
За это сообщение автора поблагодарили: jeky (2).
Старый 20.01.2004, 16:19   #9  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Wamr
Большое спасибо. После адаптации кода нормально пошел. В моем случае Query не содержит группировок.

PS: Как же не хватает нормальной документации! Буквально на "ощупь" код пишу.
Старый 20.01.2004, 20:20   #10  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
maxim, wamr, спасибо за увлекательную дискуссию.
у меня просьба, как только выйдете на обоюдоприемлимый результат, давайте его в FAQ поместим?
Старый 09.03.2005, 14:38   #11  
velk is offline
velk
Участник
 
194 / 10 (1) +
Регистрация: 17.05.2004
Может кто реализовал нормальный вариант подсчета количества???
Старый 09.03.2005, 14:51   #12  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Изначально опубликовано velk
Может кто реализовал нормальный вариант подсчета количества???
Ну, так Wamr привел код "адаптации" штатного метода SysQuery::countTotal(myQuery).

Идея заключается в том, что перебираются ВСЕ DataSource (а не только первый, как в оргинале). И во всех устанавливается подсчет Count(*).

Отлично работает.
Старый 09.03.2005, 14:52   #13  
Maxim Gorbunov is offline
Maxim Gorbunov
Administrator
Соотечественники
Лучший по профессии 2009
 
2,483 / 645 (26) +++++++
Регистрация: 27.11.2001
Адрес: Dubai, UAE
См. обсуждение по ссылке на Forum.Mazzy.RU
__________________
Not registered yet? Register here!
Have comments, questions, suggestions or anything else regarding our web site? Don't hesitate, send them to me
Старый 20.05.2010, 10:13   #15  
propeller is offline
propeller
Участник
Аватар для propeller
 
359 / 29 (1) +++
Регистрация: 25.07.2007
по ссылке
http://forum.mazzy.ru/index.php?showtopic=284&st=20
нашел код метода countPrim для 3.0
Он же подойдет для 4.0 ?
Старый 25.04.2011, 16:43   #16  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Похоже, никто не взял на себя смелость намекнуть ребятам из Microsoft, что метод подсчета количества строк в Query, если количество источников данных больше одного "немного" не правильный .

В Ax2009 они наступили на те же "грабли" в методе SysQuery.countPrim(). На первый взгляд, решение для Ax3.0 приведенное по ссылке выше вполне подходит и для Ax2009.
Старый 20.09.2011, 14:47   #17  
SHiSHok is offline
SHiSHok
Участник
Аватар для SHiSHok
Дети Юза
 
219 / 103 (4) +++++
Регистрация: 28.07.2005
Адрес: Донецк
Немного пофиксил код для запросов с группировкой: не правильно возвращает loops если запрос с группировкой возвращает 1 строку (например query такого содержания: select ItemGroupId from inventTable group by ItemGroupId where ItemGroupId=='const')

X++:
private server static container countPrim(container _queryPack)
{
...
    Integer                 iGrp;
  ;
    countQueryRun   = new QueryRun(_queryPack);
    countQuery      = countQueryRun.query();
    for (k = 1; k <= countQuery.dataSourceCount();k++)
    {
        qbds = countQuery.dataSourceNo(k);
        qbds.update(false);
        iGrp +=(qbds.orderMode()==orderMode::GroupBy); // SHiSHok.fix
        //qbds.sortClear(); // Вот этот метод сильно мешал!
        qbfl = qbds.fields();
        qbfl.dynamic(false);
        qbfl.clearFieldList();
        qbfl.addField(FieldNum(Common,recId),SelectionField::COUNT);
    }

    countQueryRun   = new QueryRun(countQuery);
    while (countQueryRun.next())
    {
        common  = countQueryRun.getNo(1);
        counter += common.recId;
        loops++;
    }
//    return [counter,((loops > 1)? loops : counter)];
    return [counter,(iGrp ? loops : counter)]; // SHiSHok.fix
}
__________________
--- SHiSHok
За это сообщение автора поблагодарили: mazzy (5), Ace of Database (5), wojzeh (1).
Старый 15.10.2013, 10:18   #18  
IvanS is offline
IvanS
Участник
Аватар для IvanS
 
241 / 44 (2) +++
Регистрация: 30.06.2006
Адрес: Екатеринбург
Цитата:
Сообщение от SHiSHok Посмотреть сообщение
Немного пофиксил код для запросов с группировкой: не правильно возвращает loops если запрос с группировкой возвращает 1 строку (например query такого содержания: select ItemGroupId from inventTable group by ItemGroupId where ItemGroupId=='const')

X++:
private server static container countPrim(container _queryPack)
{
...
    Integer                 iGrp;
  ;
    countQueryRun   = new QueryRun(_queryPack);
    countQuery      = countQueryRun.query();
    for (k = 1; k <= countQuery.dataSourceCount();k++)
    {
        qbds = countQuery.dataSourceNo(k);
        qbds.update(false);
        iGrp +=(qbds.orderMode()==orderMode::GroupBy); // SHiSHok.fix
        //qbds.sortClear(); // Вот этот метод сильно мешал!
        qbfl = qbds.fields();
        qbfl.dynamic(false);
        qbfl.clearFieldList();
        qbfl.addField(FieldNum(Common,recId),SelectionField::COUNT);
    }

    countQueryRun   = new QueryRun(countQuery);
    while (countQueryRun.next())
    {
        common  = countQueryRun.getNo(1);
        counter += common.recId;
        loops++;
    }
//    return [counter,((loops > 1)? loops : counter)];
    return [counter,(iGrp ? loops : counter)]; // SHiSHok.fix
}
Правильно ли я понял, что убрав из условия зачистку Order будет все работать нормально, как в квери с группировкой, так и без неё?
Старый 19.06.2014, 01:03   #19  
wojzeh is offline
wojzeh
Участник
Аватар для wojzeh
Соотечественники
 
674 / 512 (19) +++++++
Регистрация: 27.04.2006
Адрес: Montreal
X++:
private server static container ountPrim(container _queryPack)
{
    Query                   countQuery;
    QueryRun                countQueryRun;
    QueryBuildDataSource    qbds;
    QueryBuildFieldList     qbfl;
    Common                  common;
    Integer                 counter;
    Integer                 loops;
    
    Integer                 tmxGroupNumber;
    Integer                 tmxDataSourceNumber;
    ;
    countQueryRun   = new QueryRun(_queryPack);
    countQuery      = countQueryRun.query();
    tmxGroupNumber  = countQuery.groupByFieldCount(); //<-- this guarantees number of groupings

    for (tmxDataSourceNumber = 1; tmxDataSourceNumber <= countQuery.dataSourceCount(); tmxDataSourceNumber++)
    {
        qbds = countQuery.dataSourceNo(tmxDataSourceNumber);
         qbds.update(false);
        //qbds.sortClear();

        //tmxGroupNumber +=(qbds.orderMode()==orderMode::GroupBy); 
        qbfl = qbds.fields();
        qbfl.dynamic(false);
        qbfl.clearFieldList();
         qbds.addSelectionField(fieldNum(Common,RecId),SelectionField::Count);
    }
  
    countQueryRun   = new QueryRun(countQuery);

    while (countQueryRun.next())
    {
         common  = countQueryRun.getNo(1);
        counter += common.RecId;
        loops++;
    }
    //return [counter,loops];
    return [counter,(tmxGroupNumber ? loops : counter)];
 }
__________________
Felix nihil admirari

Последний раз редактировалось wojzeh; 19.06.2014 в 01:06.
За это сообщение автора поблагодарили: mazzy (2).
Старый 11.08.2014, 18:27   #20  
IKA is offline
IKA
Участник
 
359 / 65 (3) ++++
Регистрация: 15.03.2006
В Ax2012 R2 существует queryRun::getQueryRowCount(query, maxInt());
Кто-нибудь производительность проверял?
Теги
count, query, баг, количество, ошибка, полезное

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Как программно узнать количество промаркированных строк в гриде? Jackally DAX: Программирование 12 24.12.2007 17:16
Количество строк в Grid Eland DAX: Программирование 3 10.11.2006 15:03
Предельное количество строк в Report Владимир Максимов DAX: Программирование 1 22.12.2005 15:02
Количество строк на страницу Berkoff DAX: Программирование 2 26.10.2004 10:30
Как подсчитать количество строк в отчете ATimTim DAX: Программирование 2 21.09.2004 13:44

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

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

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