26.01.2004, 00:30 | #1 |
Участник
|
Вопрос: Существет ли какой-либо еще способ подсчитать количество строк в Query (несколько таблиц-источников), кроме тупого сканирования всех записей по while (qr.next)?
Дело в том, что это относительно медленный процесс. У меня получилось примерно 500 строк в секунду. Ответ: да, конечно, можно. <div class='XPPtop'>X++</div><div class='XPP'>SysQuery::countTotal(myQuery)</div> Причем в трехуровневой Аксапте подсчет количества записей всегда выполняется на сервере приложений. |
|
26.01.2004, 00:35 | #2 |
Участник
|
Спасибо Евгению Глазову (EVGL) за исходный совет. Спасибо Максиму Горбунову за дополнения и wamr за активное участие в обсуждении.
Обсуждение этого вопроса: как подсчитать количество записей возвращаемых Query В обсуждении этого вопроса, Максим горбунов отметил, что в текущей версии (Axapta 2.5 SP3, Axapta 2.5 SP6 CIS, Axapta 3.0 SP2) метод SysQuery::countTotal делает быстрый запрос только для простого query, который содержит только одну таблицу. Если в запросе содержится несколько связанных таблиц, то стандартный метод считает медленным и тупым сканированием записей. Максим Горбунов предложил модификацию метода SysQuery::countTotal. Модификация Максима корректно и быстро считает количество записей в запросе с несколькими связанными таблицами и с группировками. wamr отметил, что класс SysQuery содержит метод countLoops(). По сути, результат выполнения этого метода эквивалентен SQL-запросу [sql]select count(distinct myfield) from myTable[/sql] Метод countLoops()полезен когда надо вывести Progress bar. wamr предложил модификацию, которая позволяет для любого запроса считать количество группировок. В результате после этой модификации progress bar по запросам всегда будет работать правильно. <div class='XPPtop'>X++</div><div class='XPP'>SysOperationProgress progress = [color=:blue]new[/color] SysOperationProgress(); progress.setTotal(SysQuery::countLoops(qr)); [color=:blue]while[/color]( qr.[color=:blue]next[/color]() ){ [color=:green]/* ...do somthing... */[/color] progress.incCount(); }</div> Обе модифицикации затрагивают только один метод - SysQuery::countPrim(). Обратите внимание, что методы работают во всех случаях, когда запрос имеет смысл. Однако существуют запросы, когда модифицированные версии могут вызывать ошибку SQL-запроса (Exception::Error). При тестировании обнаружены запросы в которых одновременно используется связь NoExistsJoin и группировки по подчиненным таблицам. Поэтому, для неочевидных запросов используйте обрамление try/catch для работы с исключениями. Обратите также внимание, что countTotal() и countPrim() работают на сервере приложений, если у вас используется трехуровневая Аксапта. Это особенно важно, если у вас запрос с большим количеством возвращаемых группировок. SysQuery::countLoops генерирует существенно меньший трафик между клиентом и сервером, нежели "ручной" запрос с клиента. |
|
26.01.2004, 00:37 | #3 |
Участник
|
Модификация метода SysQuery::countPrim для Axapta 2.5 для быстрой работы countTotal и countLoops.
|
|
26.01.2004, 00:38 | #4 |
Участник
|
Модификация метода SysQuery::countPrim для Axapta 3.0 для быстрой работы countTotal и countLoops.
|
|
|