Каталог решений - Занимательные запросы

Занимательные запросы

Занимательные запросы

В наличии

Как выглядит "кухня" запросов 1С? Те запросы, которые пишем мы в 1С преобразуются в запросы к SQL серверу. Причём весьма неочевидным сходу способом. Рассмотрим один простой случай.

Категория:

Описание

Итак допустим мы пишем в 1С в консоли запросов:

ВЫБРАТЬ
   Товары.Ссылка,
   Товары.Поставщик.Наименование
ИЗ
   Справочник.Товары КАК Товары

В запросе к sql серверу он будет выглядеть так:

SELECT
   T1._IDRRef,
   T2._Description
   FROM _Reference7 T1
   LEFT OUTER JOIN _Reference8 T2
   ON T1._Fld109RRef = T2._IDRRef

Как видим появилось левое соединение с таблицей поставщиков. А вот если бы Товары.Поставщик мог ссылаться не только на один справочник, а на несколько, то таких соединений было бы несколько — столько же на сколько таблиц может ссылаться этот реквизит.

Вроде бы всё ясно. Но глядя в логи PgSQL мы видим что от 1С пришёл не один запрос, а ещё несколько, попроще:

SELECT
   T1._IDRRef,
   T1._Description
   FROM _Reference7 T1
   WHERE T1._IDRRef = ‘\\214\\240\\000\\015\\210C\\315\\033\\021\\334\\214\\376\\314j}\\362’::bytea
;
SELECT
   T1._IDRRef,
   T1._Description
   FROM _Reference7 T1
   WHERE T1._IDRRef = ‘\\214\\240\\000\\015\\210C\\315\\033\\021\\334\\214\\376\\314j}\\363’::bytea
;
SELECT
   T1._IDRRef,
   T1._Description
   FROM _Reference7 T1
   WHERE T1._IDRRef = ‘\\214\\240\\000\\015\\210C\\315\\033\\021\\334\\214\\376\\314j}\\364’::bytea
;
SELECT
   T1._IDRRef,
   T1._Description
   FROM _Reference7 T1
   WHERE T1._IDRRef = ‘\\214\\240\\000\\015\\210C\\315\\033\\021\\334\\214\\376\\314j}\\365’::bytea
;
SELECT
   T1._IDRRef,
   T1._Description
   FROM _Reference7 T1
   WHERE T1._IDRRef = ‘\\214\\240\\000\\015\\210C\\315\\033\\021\\334\\214\\376\\314j}\\366’::bytea
;
SELECT
   T1._IDRRef,
   T1._Description
   FROM _Reference7 T1
   WHERE T1._IDRRef = ‘\\214\\240\\000\\015\\210C\\315\\033\\021\\334\\215\\004=q\\000w’::bytea
;
SELECT
   T1._IDRRef,
   T1._Description
   FROM _Reference7 T1
   WHERE T1._IDRRef = ‘\\214\\241\\000\\015\\210C\\315\\033\\021\\334\\216\\251-\\227\\247I’::bytea
;
SELECT
   T1._IDRRef,
   T1._Description
   FROM _Reference7 T1
   WHERE T1._IDRRef = ‘\\214\\241\\000\\015\\210C\\315\\033\\021\\334\\216\\254\\324q\\326\\307’::bytea
;
SELECT
   T1._IDRRef,
   T1._Description
   FROM _Reference7 T1
   WHERE T1._IDRRef = ‘\\214\\241\\000\\015\\210C\\315\\033\\021\\334\\216\\263`\\367\\013M’::bytea
;
SELECT
   T1._IDRRef,
   T1._Description
   FROM _Reference7 T1
   WHERE T1._IDRRef = ‘\\214\\242\\000\\015\\210C\\315\\033\\021\\334\\221\\003\\235\\177\\321\\013’::bytea
;
SELECT
   T1._IDRRef,
   T1._Description
   FROM _Reference7 T1
   WHERE T1._IDRRef = ‘\\214\\242\\000\\015\\210C\\315\\033\\021\\334\\221\\016Q\\000\\330\\200’::bytea
;
SELECT
   T1._IDRRef,
   T1._Description
   FROM _Reference7 T1
   WHERE T1._IDRRef = ‘\\214\\242\\000\\015\\210C\\315\\033\\021\\334\\221\\021\\361ix.’::bytea
;
SELECT
   T1._IDRRef,
   T1._Description
   FROM _Reference7 T1
   WHERE T1._IDRRef = ‘\\215:\\000\\015\\210C\\315\\033\\021\\3352\\033\\247\\243\\012\\256’::bytea
;
SELECT
   T1._IDRRef,
   T1._Description
   FROM _Reference7 T1
   WHERE T1._IDRRef = ‘\\215:\\000\\015\\210C\\315\\033\\021\\3352\\033\\247\\243\\012\\257’::bytea

Что это за запросы? Хе! Это запросы на получение представления ссылки в результатах, отображаемых на экране.

 

Пробуем оптимизировать наш запрос. Попробуем получить представление и посмотрим сумеет ли 1С понять что оно уже получено и повторно его получать ненадо.

ВЫБРАТЬ
    Товары.Ссылка,
    Товары.Наименование,
    Товары.Представление,
    Товары.Поставщик.Наименование
ИЗ
    Справочник.Товары КАК Товары

 

В PostgreSQL пойдёт такой запрос:

SELECT
    T1._IDRRef,
    T1._Description,
    T1._IDRRef,
    T1._Description,
    T2._Description
    FROM _Reference7 T1
    LEFT OUTER JOIN _Reference8 T2
    ON T1._Fld109RRef = T2._IDRRef

но тут же в логах мы видим ещё 15 простых запросов вида

SELECT
    T1._IDRRef,
    T1._Description
    FROM _Reference7 T1
    WHERE T1._IDRRef = ‘\\214\\240\\000\\015\\210C\\315\\033\\021\\334\\214\\376\\314j}\\362’::bytea

Посчитав число отображаемых строк мы убеждаемся, что 1С не сопоставила ссылку и представление. Это вобщем логично, поскольку отображаемая таблица значений не связана с данными и поэтому 1С вынуждена подтягивать представление ссылки по мере отображения на экране.

Однако есть способ заставить 1С делать только один запрос. Для этого перепишем его вот так:

ВЫБРАТЬ
    Товары.Представление,
    Товары.Поставщик.Наименование
ИЗ
    Справочник.Товары КАК Товары
Упорядочить по
    Товары.Представление // Хочется, всё-такивидеть упорядоченные товары

При этом в Postgre отправится такой запрос

SELECT
    T1._IDRRef,
    T1._Description,
    T2._Description
    FROM _Reference7 T1
    LEFT OUTER JOIN _Reference8 T2
    ON T1._Fld109RRef = T2._IDRRef
    ORDER BY (T1._IDRRef), (T1._Description)

Запрос ушёл один, его результат отобразился без лишних обращений к базе.

Счастье? Нет!

И вот почему:

1. Несмотря на то что мы сказали «Упорядочить по Товары.Представление» произойдёт упорядочивание по внутренним идентификаторам.

2. Представление получает из базы и идентификатор и наименование, но это не даёт нам никаких преимуществ по сравнению с простой выборкой наименований поскольку идентификатор не доступен разработчику конфигурации. Из языка 1С доступно только текстовое описание.

По сути запрос к Представлению даёт меньше чем к наименованию.

ВЫБРАТЬ
    Товары.Наименование,
    Товары.Поставщик.Наименование
ИЗ
    Справочник.Товары КАК Товары
Упорядочить по
    Товары.Наименование

В PgSQL

SELECT
    T1._Description,
    T2._Description
    FROM _Reference7 T1
    LEFT OUTER JOIN _Reference8 T2
    ON T1._Fld109RRef = T2._IDRRef
    ORDER BY (T1._Description)

Эта статья навеяна двумя статьями //sale.itcity.ru/public/61624 и //sale.itcity.ru/public/61933 .

has been added to your cart:
Оформление заказа