24.08.2009, 12:29 | #1 |
Участник
|
Maximum buffer size
AX 4.0 SP2
Не выполняется SELECT. X++: static void JobMainresponsibleWhithOpenSales(Args _args) { ContactPerson ContactPerson; CustTable CustTable; SalesTable SalesTable; while select Mainresponsible from ContactPerson group by Mainresponsible exists join CustTable where CustTable.ContactPersonId == ContactPerson.ContactPersonId exists join SalesTable where SalesTable.CustAccount == CustTable.AccountNum && SalesTable.SalesStatus == SalesStatus::Backorder { info(ContactPerson.Mainresponsible); } } Суммарный внутренний размер записей в вашем объединенном операторе SELECT равен 28054 байтам, но система Microsoft Dynamics по умолчанию настроена так, что он не должен превосходить 24576 байтов. В чём криминал? Откуда превышение? Запрос возвращает только ответственных Mainresponsible. По факту их двое, т.е. две строки в результате (проверял в query analyzer) P.S.: Собирал Query в AOT таже история |
|
24.08.2009, 12:35 | #2 |
Гость
|
В настройке AOS вот тут поставь 28 или больше:
|
|
24.08.2009, 12:42 | #3 |
Участник
|
Это всё понятно. Хочется понять из-за чего происходит превышение именно в этом конкретном запросе?
|
|
24.08.2009, 12:43 | #4 |
Гость
|
Слишкий длинный запрос получается - куча таблиц со всеми полями наджойнена
|
|
24.08.2009, 12:48 | #5 |
Участник
|
Но физически же поля выбираются только из одной. Все остальные присоединены exists join.
Что именно ограничивает этот параметр? |
|
24.08.2009, 12:58 | #6 |
Гость
|
Ну х3, видимо при проверке аксапта не смотрит, какой там джойн, а тупо суммирует все поля из таблиц, и, естественно, она не проверяет количество реальных записей в таблице. Если получается, что больше, чем размер буфера - она стремается и вываливается в ошибку.
|
|
24.08.2009, 13:37 | #7 |
Участник
|
Т.е. правильно ли я понимаю, что на самом деле этот код не подходит под определение тяжёлых запросов, способных положить систему? И на самом деле это просто ложное срабатывание не совсем корректной проверки?
Смущает меня то, что весь стандартный функцианал, ведь как-то умещается в рамки стандартного буфера (встречаются запросики на первый взгляд помощнее этого). Что же такого страшного в джойне этих 3-х таблиц? Возможно размеры самих записей? Сейчас посмотрел: в каждой таблице порядка 100 полей. Выходит роковое стечение обстоятельств? |
|
24.08.2009, 13:48 | #8 |
Гость
|
Видимо так.
Я глубоко в этот вопрос не вникал, т.к. симптомы и решение всегда были очевидны. Но если ты все-таки найдешь истину - напиши потом здесь, думаю всем будет интересно. |
|
24.08.2009, 14:21 | #9 |
Member
|
Цитата:
Сообщение от S.Kuskov
...
правильно ли я понимаю, что на самом деле этот код не подходит под определение тяжёлых запросов, способных положить систему? ... Что-то у меня нигде не воспроизводится. Может вы каких полей в таблицы понадобавляли. А если писать что-то вроде exists join TableId from CustTable тоже ругается?
__________________
С уважением, glibs® |
|
24.08.2009, 14:47 | #10 |
Участник
|
Тогда тем более не понятно, чем результирующая выборка (ведь только она и будет передаваться между AOC и клиентом) неугадила?
Цитата:
У меня значение буфера не указано (по умолчанию) количество строк в таблицах ~ ContactPerson = 30, CustTable = 3000 SalesTable = 30000 В результате превышение буфера на 4 кб Да, так тоже пробовал. Не помогает |
|
24.08.2009, 14:57 | #11 |
Member
|
Цитата:
Сообщение от S.Kuskov
...
Тогда тем более не понятно, чем результирующая выборка (ведь только она и будет передаваться между AOC и клиентом) неугадила? ... AX2009 вам пишет, что Аксапта ошибается при расчете длины результирующей записи. Похоже на то, хотя я лично не могу быть уверен. Попробуйте поискать про буфер. Кажется, уже было достаточно.
__________________
С уважением, glibs® |
|
24.08.2009, 15:15 | #12 |
Участник
|
Ага. Значит это величина одной записи не влезает в буфер. Тогда действительно если посчитать все поля(Параметр Maximum buffer size в настройках AOS) всех трёх таблиц , то получается что
X++: info(int2str(SysDictTable::newTableId(tableNum(ContactPerson)).recordSize())); info(int2str(SysDictTable::newTableId(tableNum(CustTable)).recordSize())); info(int2str(SysDictTable::newTableId(tableNum(SalesTable)).recordSize())); 9396 3813 8669 Такая сумма в полне сравнима с размером буфера. Ну что ж, ситуация немного прояснилась. Остаётся только ждать и надеятся на её изменение в будущих версиях. |
|
|
За это сообщение автора поблагодарили: alex55 (1). |
24.08.2009, 17:18 | #13 |
Moderator
|
Добавлю, что этот параметр следует увеличивать крайне аккуратно, так как память указанного размере выделяется на AOS каждый раз при открытии нового соединения с БД (например, при работе с номерными сериями). Пару раз наблюдал, что чрезмерно завышенное значение данного параметра приводило к перерасходу памяти на AOS, а в предельном случае и к ее утечкам.
|
|
Теги |
ax4.0, buffer, buffer size, exists, join, maximum buffer size |
|
|