Ошибка при выполнении запроса 1С

argenon
Дата: 30.11.2014 12:41:21
Здравствуйте.

Имеем конфигурацию 1С:Предприятие 8.3 (8.3.5.1248)
Используем для работы PostgreSQL 9.2 (взятую с сайта 1С) на сервере под CentOS 6.6 x86_64.

Выполняется ресурсоемкий запрос
+

запрос.Текст = "ВЫБРАТЬ
| Организации.Ссылка КАК Организация,
| СУММА(ЕСТЬNULL(ХозрасчетныйОстатки01.СуммаОстаток, 0)) КАК СуммаОстаток01,
| ЕСТЬNULL(ХозрасчетныйОстатки0810.СуммаОстаток, 0) КАК СуммаОстаток0810,
| ЕСТЬNULL(ХозрасчетныйОстатки41.СуммаОстаток, 0) КАК СуммаОстаток41,
| ЕСТЬNULL(ХозрасчетныйОстатки51.СуммаОстаток, 0) КАК СуммаОстаток51,
| ЕСТЬNULL(ХозрасчетныйОстатки51а.СуммаОстаток, 0) КАК СуммаОстаток51а,
| ЕСТЬNULL(ХозрасчетныйОстатки50.СуммаОстаток, 0) КАК СуммаОстаток50,
| ЕСТЬNULL(ХозрасчетныйОстатки51б.СуммаОстаток, 0) КАК СуммаОстаток51б
|ИЗ
| Справочник.Организации КАК Организации
| ПОЛНОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Остатки(КОНЕЦПЕРИОДА(&Дата, ДЕНЬ), Счет В ИЕРАРХИИ (ЗНАЧЕНИЕ(ПланСчетов.хозрасчетный.ОсновныеСредства)), , ) КАК ХозрасчетныйОстатки01
| ПО Организации.Ссылка = ХозрасчетныйОстатки01.Организация
| ПОЛНОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Остатки(
| КОНЕЦПЕРИОДА(&Дата, ДЕНЬ),
| Счет В ИЕРАРХИИ (ЗНАЧЕНИЕ(ПланСчетов.хозрасчетный.ВложенияВоВнеоборотныеАктивы))
| ИЛИ Счет В ИЕРАРХИИ (ЗНАЧЕНИЕ(ПланСчетов.хозрасчетный.Материалы)),
| ,
| ) КАК ХозрасчетныйОстатки0810
| ПО Организации.Ссылка = ХозрасчетныйОстатки0810.Организация
| ПОЛНОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Остатки(КОНЕЦПЕРИОДА(&Дата, ДЕНЬ), Счет В ИЕРАРХИИ (ЗНАЧЕНИЕ(ПланСчетов.хозрасчетный.Товары)), , ) КАК ХозрасчетныйОстатки41
| ПО Организации.Ссылка = ХозрасчетныйОстатки41.Организация
| ПОЛНОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Остатки(КОНЕЦПЕРИОДА(&Дата, ДЕНЬ), Счет В ИЕРАРХИИ (ЗНАЧЕНИЕ(ПланСчетов.хозрасчетный.РасчетныеСчета)), , Субконто1.банк.код = ""xxx"") КАК ХозрасчетныйОстатки51
| ПО Организации.Ссылка = ХозрасчетныйОстатки51.Организация
| ПОЛНОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Остатки(КОНЕЦПЕРИОДА(&Дата, ДЕНЬ), Счет В ИЕРАРХИИ (ЗНАЧЕНИЕ(ПланСчетов.хозрасчетный.РасчетныеСчета)), , Субконто1.банк.код = ""xxx"") КАК ХозрасчетныйОстатки51а
| ПО Организации.Ссылка = ХозрасчетныйОстатки51а.Организация
| ПОЛНОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Остатки(КОНЕЦПЕРИОДА(&Дата, ДЕНЬ), Счет В ИЕРАРХИИ (ЗНАЧЕНИЕ(ПланСчетов.хозрасчетный.Касса)), , ) КАК ХозрасчетныйОстатки50
| ПО Организации.Ссылка = ХозрасчетныйОстатки50.Организация
| ПОЛНОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Остатки(КОНЕЦПЕРИОДА(&Дата, ДЕНЬ), Счет В ИЕРАРХИИ (ЗНАЧЕНИЕ(ПланСчетов.хозрасчетный.РасчетныеСчета)), , Субконто1.банк.код = ""ххх"") КАК ХозрасчетныйОстатки51б
| ПО Организации.Ссылка = ХозрасчетныйОстатки51б.Организация
|ГДЕ
| Организации.ИНН <> ""ххх""
|
|СГРУППИРОВАТЬ ПО
| Организации.Ссылка,
| ЕСТЬNULL(ХозрасчетныйОстатки0810.СуммаОстаток, 0),
| ЕСТЬNULL(ХозрасчетныйОстатки41.СуммаОстаток, 0),
| ЕСТЬNULL(ХозрасчетныйОстатки51.СуммаОстаток, 0),
| ЕСТЬNULL(ХозрасчетныйОстатки51а.СуммаОстаток, 0),
| ЕСТЬNULL(ХозрасчетныйОстатки50.СуммаОстаток, 0),
| ЕСТЬNULL(ХозрасчетныйОстатки51б.СуммаОстаток, 0)
|
|УПОРЯДОЧИТЬ ПО
| Организации.Наименование";


База данных весит около 1.2 ГБ, во время выполнения запроса в оперативной памяти занимает 10 ГБ. Данные примерно за 2 года.
Понимаю, что запрос не оптимальный, но программисты наотрез отказываются его менять ссылаясь на то, что на MSSQL он работает.

автор
В результате выполнения 1С выдает ошибку

Невосстановимая ошибка
Ошибка при выполнении запроса POST к ресурсу /e1cib/logForm:
по причине:
Ошибка СУБД:
ERROR: too many range table entries


Попытка разобраться с помошью гугла к успеху не привела. Единственное, что я обнаружил это комментарий в исходном коде PostgreSQL

автор
/*
* Check for RT index overflow; it's very unlikely, but if it did happen,
* the executor would get confused by varnos that match the special varno
* values.
*/
if (IS_SPECIAL_VARNO(list_length(glob->finalrtable)))
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("too many range table entries")));


Хотелось бы понять из-за чего возникает такая проблема и как ее можно устранить.
спойлер
Дата: 30.11.2014 14:41:09
argenon,

перейдите на мсскл
или увольте кодеров

1-е -- проще
2-е -- чревато необходимостью много что переписывать в 1С, за 1С, поперёк 1С

а ошибка -- это 1С
-- "но ведь других нет"(СС)

так что переходите на мсскл и не парьте мозги


+ спойлер

#define IS_SPECIAL_VARNO 	( 	  	varno	) 	   ((varno) >= INNER_VAR)

#define INNER_VAR   65000 /* reference to inner subplan */
argenon
Дата: 30.11.2014 14:54:21
спойлер,

тут уже дело принципа - понять что происходит.
Поясните, пожалуйста, про INNER_VAR
Maxim Boguk
Дата: 30.11.2014 15:28:49
argenon
спойлер,

тут уже дело принципа - понять что происходит.
Поясните, пожалуйста, про INNER_VAR


Для начала посмотрите в какой SQL запрос преобразуется вышеприведенный птичий язык... это раз (перевести с птичьего языка на нормальный SQL не всегда просто)...
два - посмотрите нет ли там партиционирования в тех или иных таблицах учатсвующих в запросе.
По логике эта ошибка может только при партиционировании возникать.

--Maxim Boguk
www.postgresql-consulting.ru
argenon
Дата: 30.11.2014 15:54:06
Maxim Boguk,

SQL запрос у меня есть в логе posqtgresql, но не знаю, как бы обезличить данные. Если только очистить таблицы.

Про партиционирование 1с-прораммисты не слышали.

В конфиге postgresql установлено значение
constraint_exclusion = partition
спойлер
Дата: 30.11.2014 17:08:04
Maxim Boguk
argenon
спойлер,

тут уже дело принципа - понять что происходит.
Поясните, пожалуйста, про INNER_VAR


Для начала посмотрите в какой SQL запрос преобразуется вышеприведенный птичий язык... это раз (перевести с птичьего языка на нормальный SQL не всегда просто)...
два - посмотрите нет ли там партиционирования в тех или иных таблицах учатсвующих в запросе.
По логике эта ошибка может только при партиционировании возникать.

--Maxim Boguk
<>


поскольку там
	Счет В ИЕРАРХИИ 

то это может быть отнюдь не "один "SQL запрос", а как минимум свёртка с времянками. (1С любит некоторые выборки COPY FROM STDOUT во времяночки, а потом чутка с ними возиться)

или даже наброс кучи подвыборок "вдоль иерерахий" в такие времянки, с последующей сверткой.

(эта конструкция и способы её реализации в 1С появились задолго до появлений в субд-ах кляузы "with recursive", и вряд ли её, т.е. коснтрукции, реализацию с тех пор переписывали , тем паче -- субд -зависимым способом )

т.е. в этом случае имеет место быть не простая "трансляция", а трансляция с изподвывертом.


да и тип свёртки -- full join -- не подарок

Опять же , шняги типа
РегистрБухгалтерии.Хозрасчетный.Остатки(
       КОНЕЦПЕРИОДА(&Дата, ДЕНЬ)
       ,Счет В ИЕРАРХИИ (ЗНАЧЕНИЕ(ПланСчетов.хозрасчетный.ОсновныеСредства)), , )
  КАК ХозрасчетныйОстатки01
-- это не таблицы, а некоторые, скорее всего организованные через те же времянки "параметрические" выборки [из таблиц остатков -- сиречь "регистров"]. (могли бы быть хранимками, но это не 1С-вэй).


ps 2тс:
а что пояснять -- есть некая тупая константа -- 65000. вы за неё выкатились. с чем вас и поздравляем.
laskin82
Дата: 30.11.2014 20:08:47
argenon, Пожалуйста, "не грузите" местных, а лучше дайте почитать вашим 1С разработчикам

1) http://its.1c.ru/db/metod8dev#content:1556:hdoc

"Использование конструкции ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ

В СУБД PostgreSQL реализована только частичная поддержка FULL OUTER JOIN (ERROR: "FULL JOIN is only supported with mergejoinable join conditions"). Для реализации полной поддержки FULL OUTER JOIN при работе 1С:Предприятия 8 с PostgreSQL подобный запрос трансформируется в другую форму с эквивалентным результатом, однако эффективность использования конструкции ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ снижается.

В связи с этим не рекомендуется использовать ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ при работе с PostgreSQL. В большинстве случаев без использования этой конструкции можно обойтись, переписав исходный запрос."
laskin82
Дата: 30.11.2014 20:11:11
argenon, а потом пусть читают до просветления http://kb.1c.ru/articleView.jsp?id=44 (Типичные причины неоптимальной работы запросов и методы оптимизации)
kihor
Дата: 30.11.2014 20:59:18
argenon,

На мой взгляд запрос не действительно не оптимальный, т.к. виртуальные таблицы остатков преобразуются в подзапросы, а соединение подзапросов может поставить в тупик оптимизатор (заставит сгенерировать неоптимальный план). Можно запрос переписать с использованием временных таблиц.
Да, и действительно, не рекомендуют использовать FULL OUTER JOIN на Postgres.
argenon
Дата: 30.11.2014 21:38:56
Спасибо за советы.
Выложу SQL запрос, который формирует 1с.
Запрос оказался не маленьким поэтому только в виде архива.
https://yadi.sk/d/ujT5Z4brd49yn
Может кому-то будет интересно взглянуть.