Контакти

1з 8 пакетний запит. Прості запити. Причини неоптимальної роботи запитів

Розберемо, як змінювався (швидше доповнювався) синтаксис текстів запитів на простому прикладі: Проводиться документ Витратнамістить у табличній частині Товарисписок товарів і кількість. При проведенні такого документа необхідно забезпечити контроль негативних залишків залишків, що зберігаються в регістрі накопичення. ЗалишкиТоварів.

Структура конфігурації представлена ​​малюнку.

(16.22 кілобайт) Кількість скачувань: 64

Сформуємо запит до табличної частини документа та віртуальної таблиці Залишкирегістру накопичення. Врахуємо можливі дублі рядків у документі, для цього зробимо групування записів.

Запит = Новий Запит;
Запит.Текст = "
| ВИБРАТИ
| Номенклатура,
| СУМА(Док.Кількість) ЯК Док_Кількість,
| МІНІМУМ(Є NULL(Рег.КількістьЗалишок,0)) ЯК Рег_Кількість

| Документ.Видаткова.Товари ЯК Док
| ЛІВОЕ З'ЄДНАННЯ
| РеєстрНакопичення.ЗалишкиТоварів.Залишки() ЯК Реєстр
| ПЗ
| Док.Номенклатура = Реєстр.Номенклатура
|ДЕ
| Посилання = Посилання
|ЗГРУПУВАТИ ЗА Док.Номенклатура";

//Проведення з регістру

КінецьЦикл;

КінецьПроцедури

Природно наведений запит абсолютно не є оптимальним. За допомогою вкладених запитів оптимізуємо його: Зробимо групування табличної частини документа до з'єднання з таблицею залишків, параметри віртуальної таблиці передамо список товарів як значення умови для розрахунку залишків. У результаті наш запит набуде наступного вигляду:

| ВИБРАТИ
| Номенклатура,


| (ВИБРАТИ

| З
| Документ.Видаткова.Товари
| ДЕ
| Посилання = Посилання
| ЗГРУПУВАТИ ПО Номенклатурі) ЯК Док
| ЛІВОЕ З'ЄДНАННЯ
Номенклатура В
| (ВИБРАТИ РІЗНІ
| Номенклатура
| З
| Документ.Видаткова.Товари
| ДЕ
| Посилання = Посилання)) ЯК Рег
| ПЗ

Якби в запиті необхідно було б отримати дані із залишків різних регістрів то значення фільтра, а отже і наш другий вкладений запит, повторювався б у всіх параметрах віртуальних таблиць, природно, що система при кожному вкладеному запиті наново звертається до бази даних для отримання даних.

Тимчасові таблиці

Не пам'ятаю вже з якого релізу в запитах можна використовувати тимчасові таблиці. Для цього використовується об'єкт "Менеджер тимчасових таблиць". Фактично менеджер тимчасових таблиць визначає простір імен тимчасових таблиць та відповідає за їх створення та знищення у базі даних.

Самі часові таблиці справді фізично створюються основою, відповідно слід ставитися до них обережно, оскільки дискова підсистема нині найповільніша частина техніки, а швидкість створення та знищення таблиць безпосередньо від неї залежить.

Перепишемо запит для використання часових таблиць. У тимчасові таблиці помістимо згруповану табличну частину документа та список товарів для фільтра віртуальних таблиць:

Процедура ОбробкаПроведення(Відмова, РежимПроведення)

МВТ = Новий Менеджер Тимчасових Таблиць;

Запит = Новий Запит;
Запит.Текст = "
| ВИБРАТИ
| Номенклатура, СУМА(Кількість) ЯК Кількість
|ПОМІСТИТИ ДокТЧ

| Документ.Видаткова.Товари
|ДЕ
| Посилання = Посилання
|ЗГРУПУВАТИ ПО Номенклатурі ";

Запит = Новий Запит;
Запрос.Менеджер Тимчасових Таблиць = МВТ;
Запит.Текст = "ВИБРАТИ РІЗНІ
| Номенклатура
|ПОМІСТИТИ СписокТоварів |

| Документ.Видаткова.Товари
|ДЕ
| Посилання = &Посилання";

Запит = Новий Запит;
Запрос.Менеджер Тимчасових Таблиць = МВТ;
Запит.Текст = "
| ВИБРАТИ
| Номенклатура,
| Док.Кількість ЯК Док_Кількість,
| ЄNULL(Рег.КількістьЗалишок,0) ЯК Рег_Кількість

| ДокТЧ ЯК Док
| ЛІВОЕ З'ЄДНАННЯ
| РегістрНакопичення. Залишки Товарів. Залишки (,
| Номенклатура
| З
| ПЗ
| Док.Номенклатура = Реєстр.Номенклатура";

РезультатЗапиту = Запит.Виконати();
Вибірка = Результат Запиту. Вибрати ();

Поки Вибірка.Наступний() Цикл

//Перевірка негативних залишків

//Проведення з регістру

КінецьЦикл;

КінецьПроцедури

При використанні тимчасових таблиць у тексті запиту застосовують інструкцію Поміститидля створення нової тимчасової таблиці, в цьому випадку в результат запиту система передає не вміст цієї таблиці (див 1 і 2 в тексті вище), а кількість записів поміщених в тимчасову таблицю, за бажанням можна не приймати це значення.

Також допускається використання інструкції Знищитив цьому випадку тимчасова таблиця знищується, інакше тимчасові таблиці знищуються разом з об'єктом менеджер тимчасових таблиць.

В основному нашому запиті я використовував назви часових таблиць як вказівку на джерело отримання даних (їм обов'язково треба призначати синонім, що ми бачимо в тексті). Використовувати тимчасові таблиці як джерело можна неодноразово, що з вмілому їх застосуванні дозволить скоротити текст запиту (поліпшитися читабельність складних запитів) і збільшити швидкість (при використанні даних тимчасової таблиці у кількох місцях запиту).

Пакетні запити

Пакетні запити логічно доповнюють функціонал тимчасових таблиць та дають більше можливостей під час роботи із запитами.

У пакетному запиті фактично можна описати кілька запитів, як пов'язаних між собою використанням тимчасових таблиць, і не пов'язаних (можна, але зрозуміло навіщо?). У результаті можна виконати послідовно всі запити і прийняти в результаті масив з результатами виконання кожного запиту, або результат останнього. Для отримання масиву з результатами запиту застосовують метод Виконати Пакет()об'єкта запит, а для отримання результату останнього запиту Виконати запит().

У тексті запиту, запити пакета поділяються символом ";" (крапка з комою). Область імен віртуальних таблиць одного пакетного запиту одна. Використання менеджера тимчасових таблиць не потрібне, але можливо, якщо ви хочете передати тимчасові таблиці з одного пакетного запиту до іншого.

Перепишемо процедуру для використання пакетних запитів:

Процедура ОбробкаПроведення(Відмова, РежимПроведення)

Запит = Новий Запит;
Запит.Текст = "
| ВИБРАТИ
| Номенклатура, СУМА(Кількість) ЯК Кількість
|ПОМІСТИТИ ДокТЧ

| Документ.Видаткова.Товари
|ДЕ
| Посилання = Посилання
|ЗГРУПУВАТИ ЗА Номенклатурою
|;
|ВИБРАТИ РІЗНІ
| Номенклатура
|ПОМІСТИТИ СписокТоварів |

| Документ.Видаткова.Товари
|ДЕ
| Посилання = Посилання
|;
| ВИБРАТИ
| Номенклатура,
| Док.Кількість ЯК Док_Кількість,
| ЄNULL(Рег.КількістьЗалишок,0) ЯК Рег_Кількість

| ДокТЧ ЯК Док
| ЛІВОЕ З'ЄДНАННЯ
| РегістрНакопичення. Залишки Товарів. Залишки (,
| Номенклатура В(ВИБРАТИ РІЗНІ
| Номенклатура
| З
| СписокТоварів ЯК СписокТоваров)) ЯК Реєстр
| ПЗ
| Док.Номенклатура = Реєстр.Номенклатура";

Поки Вибірка.Наступний() Цикл

//Перевірка негативних залишків

//Проведення з регістру

КінецьЦикл;

КінецьПроцедури

Фактично я прибрав визначення об'єкта запит та використання менеджера часових таблиць, об'єднав тексти запитів (зверніть увагу на роздільник «;» між текстами). В результаті текст запиту став більш читабельним (а при використанні конструктора запитів набагато збільшується зручність читання запиту).

Після виконання запиту до змінної МасивРезультатіву нас потрапить 3 елементи. Перші два будуть містити число, що характеризує кількість записів, поміщених у тимчасові таблиці. ДокТЧі Список товарів, а третій міститиме вибірку з полями Номенклатура, Док_ Кількістьі Рег_ Кількість.

У змінну РезультатЗапитупотрапить лише вибірка.

Ну от і все щодо пакетних запитів. Дуже зручний механізм і з погляду написання запитів, і з погляду читання складних запитів.

Платформа «1С Підприємство» дозволяє виконати кілька запитів за один раз. У 1С це називається пакетом запитів. У межах одного пакета кожен запит поділяється «точкою з комою».

Для досягнення поетапного виконання запитів у пакеті, як правило, спочатку створюються часові таблиці, потім формуються умови їхнього спільного використання, такі як фільтри, з'єднання, об'єднання. Завдяки цьому досягається кінцевий результат. Тимчасові таблиці, отримані внаслідок будь-яких запитів у пакеті, продовжують існувати до закінчення виконання пакета в цілому або до виконання запиту, який знищує тимчасові таблиці.

Крім того, використання пакетних запитів та тимчасових таблиць значно підвищує читаність всього відрізка цього коду. Складні запити, що містять ще й вкладені запити, бувають дуже важкими до сприйняття. Однак якщо розбити довгий складний запит на кілька, та ще й використовувати часові таблиці, то це дозволить домогтися не тільки підвищення сприйняття, а й у більшості випадків призводить до підвищення продуктивності.

Ще одна важлива деталь на користь пакетних запитів у 1С – це те, що на відміну від нас можемо отримати окремо результат кожного запиту в пакеті.

Приклад створення пакета запитів мовою 1С

Щоб побачити приклад, як створити пакет запитів, будемо використовувати конструктор запитів, який викличемо для наочності з консолі запитів. Таким чином, зможемо одразу подивитися результат виконання пакету.

Створимо простий пакетний запит. Пропоную відразу вставити текст запиту в , а потім відкрити та подивитися, як формується пакет запитів. Додайте новий запит у консоль і вставте наступний текст:

Отримайте 267 відеоуроків з 1С безкоштовно:

Госпрозрахунковий.Посилання,
Госпрозрахунковий.Батько,
Госпрозрахунковий.
Госпрозрахунковий.КодШвидкогоВибору,
Госпрозрахунковий.Найменування,
Госпрозрахунковий.
Госпрозрахунковий.
Госпрозрахунковий.Кількісний,
З
ПланРахунків.Госпрозрахунковий ЯК Госпрозрахунковий
ДЕ
Госпрозрахунковий.Посилання = &Рахунок
;
////////////////////////////////////////////////////////////////////////////////

ВИБРАТИ
ГоспрозрахунковийВидиСубконто.НомерРядки ЯК НомерРядки,
ГоспрозрахунковийВидиСубконто.ВидСубконто ЯК ВидСубконто,
ГоспрозрахунковийВидиСубконто.ВидСубконто.Найменування ЯК Найменування,
ГоспрозрахунковийВидиСубконто.ВидСубконто.ТипЗначення ЯК ТипЗначення,
ГоспрозрахунковийВидиСубконто.ТількиОбороти ЯК ТількиОбороти,
ГоспрозрахунковийВидиСубконто.Суммовий ЯК Сумовий
З
План Рахунків.Госпрозрахунковий.ВидиСубконто ЯК ГоспрозрахунковийВидиСубконто
ДЕ
ГоспрозрахунковийВидиСубконто.Посилання = &Рахунок
ВПОРЯДКУВАТИ ЗА
ГоспрозрахунковийВидиСубконто.НомерРядки

У мене це виглядає так:

Тепер перейдемо до конструктора запитів. Тут нас цікавитиме закладка «Пакет запитів»:

Як бачимо, у нас з'явився пакет із двох запитів. Клікнувши двічі на будь-якому з них, можна перейти до його редагування:

Натисніть кнопку «Ок» і спробуємо переглянути результат виконання пакетного запиту.

Встановимо параметр «Рахунок». Можна вибрати будь-який рахунок із плану рахунків. Як Ви вже, напевно, здогадалися, цей пакет запитів має отримати властивості рахунку. Натискаємо «Виконати» та дивимося результат:

Методи Виконати() та ВиконатиПакет()

Коли мій запит став таким складним, що перевищив межі мого розуміння, я вирішив використати пакетні запити.

Але зіткнувся з фактом, що про них нічого не знаю. Виявилося, що все дуже просто. Через 5 хвилин ви вмітимете користуватися пакетними запитами. Починайте читати.

Як виявилося, все дуже просто. Потрібно просто написати кілька запитів, розділених крапкою з комою. Результат повернеться до останнього запиту.

Пакетні запити з'явилися лише у версії 8.1.11.67.4.

Ось текст запиту:

ВИБРАТИ Т1.Зн ПОМІСТИТИ ВТБукви З (ВИБРАТИ "А" ЯК ЗН ОБ'ЄДНАТИ ВСЕ ВИБРАТИ "Б") ЯК Т1;

ВИБРАТИ Т1.Зн ПОМІСТИТИ ВТЦИФРИ З (ВИБРАТИ "1" ЯК ЗН ОБ'ЄДНАТИ ВСЕ ВИБРАТИ "2") ЯК Т1;

ВИБРАТИ ТБ.Зн, ТЦ.Зн, ТБ.Зн+ТЦ.Зн З ВТБукви ЯК ТБ, ВТЦифри ЯК ТЦ

Пакетні запити підтримуються у будь-якій звичайній консолі запитів.

На малюнку представлений зразок виконання запиту:

А тепер трохи із досвіду. Для чого потрібні пакетні запити.

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

Раніше, коли не було тимчасових таблиць, довелося дублювати текст запиту.

Можна звичайно обійтися без пакетного запиту, послідовно виконуючи кілька запитів і маніпулюючи вкладеними таблицями. Але з пакетними запитами зручніше. Просто пишеш запит і не думаєш про розміщення тимчасових таблиць. Все відбувається саме.

Крім того, якщо використовується система компонування даних (СКД), вона грамотно відбирає потрібні поля та мінімізує весь пакет запитів.

Якщо запити мали метод Запит.Виконати()то тепер з'явився метод Запит.Виконати Пакет(), який повертає всі таблиці з пакета у вигляді масиву.

Анонс пакетних запитів на сайті 1с знаходиться тут: http://v8.1c.ru/overview/release_8_1_11/#Functional

Історія з життя

Поясню, що мене спонукало на пакетні запити.

Значить, уявіть документ, у нього таблична частина. У колонці « Помилка» ознака, чи є помилка під час заповнення документа. У колонці « ТекстПомилки» може бути одна або кілька речень з текстами помилок. Види помилок, які у пропозиціях відомі заздалегідь.

Так ось, ми заносимо список усіх помилок до таблиці КодиПомилок- там міститься код помилки та підрядок пошуку.

Отримуємо для кожного рядка одну, дві чи більше помилок. Т.к. В одному рядку може бути кілька помилок.

Але помилка то, можливо і розпізнана, тобто. прапор « Помилка» стоїть, а текст помилки не дав нам код помилки.

Робимо ліве з'єднання, там, де код помилки є NULL, даємо код помилки. Інші помилки» .

Але проблема в тому, що кодів помилок було близько 200, тому ліве з'єднання працювало дуже довго. Довелося замінити його на внутрішню сполуку, яка літала. Але при цьому губилися рядки, для яких помилки не було знайдено. Я так і не зміг зрозуміти, як витягти ці рядки у результат.

Запит писався системи компонування, тобто. ніяких таблиць значень чи тимчасових таблиць застосовувати не можна у принципі. Тут і стали в нагоді пакетні запити.

Я просто ще раз поєднав усі рядки з помилками з усіма рядками, для яких було знайдено помилки, і додав все-таки вид помилки «Інші помилки».

У статті розповідається про механізм пакетних запитів, реалізованих у платформі «1С:Підприємство». Прочитавши статтю, ви дізнаєтесь:

  • Що таке пакетні запити та для чого вони потрібні?
  • Як створити пакет запитів за допомогою конструктора?
  • Як повернути масив результатів кожного запиту з пакета?

Застосовність

Матеріал є актуальним для поточних версій платформи «1С:Підприємство» редакції 8.3

Призначення пакета запитів

Платформа дозволяє працювати із пакетами запитів. Отримуємо можливість виконати кілька запитів за раз. У пакетному запиті тексти запитів поділяються символом ";" (крапка з комою).

Запити виконуються послідовно, при цьому тимчасові таблиці, які були створені під час виконання будь-якого запиту, існуватимуть до закінчення виконання всього пакета запиту або до виконання пакета запиту, що знищує цю тимчасову таблицю. Важлива відмінністьвід вкладеного запиту полягає в тому, що результати кожного запиту пакета доступні окремо.

Пакети запитів дозволяють досягти поетапного виконання запиту. Для цього в пакетному запиті спочатку відбувається створення тимчасових таблиць, далі їх спільне використання (з'єднання, об'єднання, фільтри) для отримання підсумкового результату запиту. Також важливо відзначити, що використання тимчасових таблиць у пакетних запитах дозволяє покращити читання тексту запиту.

Об'ємні запити із загорнутими один одного вкладеними запитами найчастіше бувають досить складними сприйняття. Але якщо переписати такий запит з використанням тимчасових таблиць, наочність запиту може підвищитись досить сильно. Застосування пакета запитів з тимчасовими таблицями може також підвищити продуктивність запиту.

Існують методики оптимізації продуктивності запитів, що ґрунтуються на заміні вкладених запитів на тимчасові таблиці.

Тимчасова таблиця може бути корисна, коли необхідно використовувати ті самі дані у великому запиті кілька разів, наприклад, з'єднуючи або об'єднуючи з іншими таблицями. При використанні вкладених запитів такі дані довелося б отримувати кілька разів за допомогою однакових вкладених запитів, що, безумовно, позначилося б і читання тексту, і на продуктивності.

Створення пакета запитів за допомогою конструктора

Окремі запити, що входять у пакет, відокремлюються у тексті символом ";" (крапка з комою). Щоб не розділяти текст запиту вручну, можна використовувати конструктор запитів.
Конструктор запитів має окрему закладку для пакетів запитів. Запити до пакета можна додавати за допомогою відповідної кнопки на командній панелі, а також пересувати вгору або вниз.

Візуальне відображення окремих запитів – закладки у правій частині конструктора, які можна перейти до редагування тексту окремого запиту. На цих закладках для тимчасових таблиць виводяться імена, для запитів вибірку даних – «Запит пакета 2» тощо, на знищення – «– ИмяВТ».

Також у списку таблиць бази даних з'являються тимчасові таблиці, створені в рамках даного пакету. Однак це не означає, що тимчасові таблиці зберігаються в базі даних разом з іншими таблицями інформаційної бази.

Виконання запитів пакету

Якщо об'єкту Запит, що виконує пакетний запит, встановлено менеджер тимчасових таблиць, тимчасові таблиці, які були знищені рамках пакетного запиту, збережуться у встановленому менеджері.

У тексті пакетного запиту можливе використання та знищення часових таблиць, які існували у встановленому менеджері часових таблиць на момент запуску пакета на виконання.

Крім методу Виконати(), що послідовно виконує всі запити пакета та повертає результат останнього запиту в пакеті, у платформі існує ще один метод – Виконати Пакет().

Цей метод послідовно виконує всі запити і повертає масив результатів кожного запиту з пакета в послідовності розташування запитів у тексті пакета.

Результатом виконання запиту на знищення тимчасової таблиці є значення Не визначене, яке також міститься в масив результатів.

Ця стаття розрахована на читачів, які знайомі з мовою SQL.

Мова запитів у 1С, що застосовується починаючи з версії 8, сьогодні стала корисним інструментомдо роботи з базами даних, що дозволяє читати їх, але з записывать. Синтаксично мова запитів дуже схожа з мовою SQL, але російською мовою.

Нижче наведено таблицю відповідності основних операторів мови запитів та SQL:

Оператори мови запитів 1С

Оператор SQL

РІЗНІ

З'ЄДНАННЯ

ЗГРУПУВАТИ ПО

ОБ'ЄДНАТИ

ВПОРЯДКУВАТИ ЗА

І це далеко не повний список. Більш повну довідкову інформаціюпо доступним оператораммови запитів можна отримати у конструкторі запитів, про який буде розказано нижче.

Виконання запиту 1С із програмного кодуздійснюється за допомогою об'єкта вбудованої мови "Запит". Приклад написання запиту до бази даних із використанням вбудованої мови програмування:

Запит = Новий Запит; Запрос.Текст = "ВИБРАТИ | Синонім.Посилання ЯК Посилання |З | Довідник.Довідник1 ЯК Синонім"; Вибірка = Запит.Виконати().Вибрати(); Поки Вибірка.Наступний() Цикл // Вставити обробку вибірки ВибіркаДетальніЗаписи КінецьЦикл;

Метод «Виконати» виконує запит, метод «Вибрати» повертає значення типу «Вибірка Результату Запиту». Можна також використовувати метод «Вивантажити», який повертає таблицю значень.

Параметри запиту зберігаються як «Параметри» (у разі це структура, тому всі методи структури тут застосовні – вставити, видалити тощо.).

Приклад установки параметра «Запит.Параметри.Вставити» («Довідник», ДовідникПосилання). У запиті звернутися до параметрів можна за допомогою амперсанд «&Довідник». Нижче наведено приклад запиту з використанням параметрів:

Запит = Новий Запит; Запит.Текст = "ВИБРАТИ | Користувачі.Посилання ЯК Посилання, | Користувачі.Батько ЯК Батько, | Запит.Параметри.Вставити("Довідник", ДовідникПосилання); Вибірка = Запит.Виконати().Вибрати(); Поки Вибірка.Наступний() Цикл // Вставити обробку вибірки ВибіркаДетальніЗаписи КінецьЦикл;

Нагадаємо, що мова запитів призначена лише для читання даних із бази, тому в ній відсутні аналоги таких операторів SQL, як INS ERT та UPDATE. Дані можна модифікувати лише через об'єктну модель вбудованої мови програмування 1С. Також у мові запитів 1С існують оператори, аналогів яких немає в SQL, наприклад:

  • В ІЄРАРХІЇ
  • ПОМІСТИТИ
  • ІНДЕКСУВАТИ ПО

В ІЄРАРХІЇ– дозволяє вибрати всі елементи ієрархічного довідника, які входять до ієрархії переданого посилання. Приклад запиту з використанням В ІЄРАРХІЇ:

ВИБРАТИ Товари.Посилання, Товари.Артикул З Довідник.Товари ЯК Товари ДЕ Товари.Посилання В ІЄРАРХІЇ(&Цитрусові)"

В даному випадку в результат повернуться всі підлеглі елементи довідника номенклатури «Цитрусові», байдуже, скільки рівнів ієрархії має даний довідник.

Також, наприклад, є завдання знайти товар з ім'ям «Ручка». Товар має входити до ієрархії «Канц. Товарів», тобто нам не треба шукати ручку дверей. Структура номенклатури у разі така:

Канцелярія

|_ Ручки пір'яні |_ Ручка червона |_ Ручка синя |_ Ручки чорнильні |_ Лінійки

Фурнітура

|_ Ручки дверні |_ Ручка дверна проста |_ Ручка дверна люкс |

Пишемо такий запит:

ВИБРАТИ Товари.Посилання, Товари.Артикул З Довідник.Товари ЯК Товари ДЕ Товари.Найменування Подібно "Ручка%" І Товари.Посилання В ІЄРАРХІЇ(&Канцелярія)"

При використанні конструкції В ІЄРАРХІЇнеобхідно враховувати, що якщо параметр «Канцелярія» передати порожнє посилання, виконання запиту сповільниться, оскільки платформа перевірятиме кожен елемент на приналежність кореню.

ПОМІСТИТИ– Цей оператор поміщає результат у тимчасову таблицю. Приклад запиту:

ВИБРАТИ Користувачі.Посилання ЯК Посилання, Користувачі.Батьки ЯК Батько, Користувачі.Найменування ЯК Найменування ПОМІСТИТИ ВідібраніКористувачі З Довідник.Користувачі ЯК Користувачі ДЕ Користувачі.Посилання = &Довідка ВИБРАТИ ВідібраніКористувачі.Посилання ЯК Посилання, ВідібраніКористувачі.Батько ЯК Батько, ВідібраніКористувачі.Найменування ЯК Найменування З ВідібраніКористувачі ЯК ВідібраніКористувачі

Цей запит на SQL буде виконаний кількома запитами:

  • створення тимчасової таблиці (платформа вміє «перевикористовувати» раніше створені тимчасові таблиці, тому створення відбувається який завжди);
  • Приміщення даних у тимчасову таблицю;
  • Виконання основного запиту, а саме SEL ECT із цієї тимчасової таблиці;
  • Знищення/очищення часової таблиці.

Тимчасова таблиця може бути знищена явно через конструкцію ЗНИЩИТИ, або неявно – під час закриття менеджера тимчасових таблиць.

Об'єкт «Запит» вбудованої мови програмування має властивість «Менеджер Тимчасових Таблиць», яка призначена для роботи з тимчасовими таблицями. Приклад коду:

МВТ = Новий Менеджер Тимчасових Таблиць (); Запит = Новий Запит; Запрос.Менеджер Тимчасових Таблиць = МВТ;

Після виконання запиту змінну МВТ можна використовувати вдруге іншому запиті, що, безсумнівно, є ще одним плюсом використання тимчасових таблиць. У цьому випадку тимчасова таблиця з бази буде видалена при виклику методу «Закрити».

МВТ.Закрити();

...або ж при очищенні змінної з пам'яті, тобто при виконанні методу, в якому була оголошена змінна. Тимчасові таблиці підвищують навантаження на дискову підсистему, тому слід створювати дуже багато тимчасових підсистем (у циклі, наприклад), чи підсистем великого обсягу.

ІНДЕКСУВАТИ ПО– цей оператор застосовується разом із оператором ПОМІСТИТИ.При створенні тимчасової таблиці цим оператором можна проіндексувати створювану таблицю, що суттєво прискорює роботу з нею (але якщо індекс підходить під ваш запит).

Безкоштовна консультація експерта

Дякуємо за Ваше звернення!

Спеціаліст 1С зв'яжеться з вами протягом 15 хвилин.

Особливості деяких операторів мови запитів

ДЛЯ ЗМІНИданий операторпризначений для блокування певної таблиці запиту (або всіх таблиць, які беруть участь у запиті). Блокування здійснюється накладенням блокування U на таблицю. SQL це реалізується через hint UPDLOCK. Ця конструкція необхідна для запобігання блокуванням типу deadlock. Приклад запиту з конструкцією ДЛЯ ЗМІНИ:

ВИБРАТИ Користувачі.Посилання ЯК Посилання, Користувачі.Батько ЯК Батько, Користувачі.Найменування ЯК Найменування З Довідник.Користувачі ЯК Користувачі ЛІВОЕ З'ЄДНАННЯ Довідник.РФК ЯК РФК ПОГЛ.

У даному прикладі U блокування буде встановлено на таблицю "Користувачі". Якщо не вказувати таблицю для блокування, вона буде накладена на всі таблиці, які беруть участь у запиті. Ця конструкція працює тільки в конфігураціях, в яких включений автоматичний режимуправління блокуванням.



З'ЄДНАННЯ– запит підтримує з'єднання ЛІВА/ПРАВА, ПОВНА, ВНУТРІШНЯ,що відповідає з'єднанням SQL - LEFT/RIGHT JOIN, OUTER JOIN, INNER JOIN.

Однак при використанні конструктора запитів ви не зможете зробити ПРАВА З'ЄДНАННЯ.Конструктор просто мінятиме місцями таблиці, але оператор буде завжди лівий. З цієї причини в 1С ніколи не зустрінеш застосування правої сполуки.

Синтаксично з'єднання виглядає так:

ВИБРАТИ Таблиця1.Посилання ЯК Посилання З Довідник.Довідник1 ЯК Таблиця1 ЛІВОЕ З'ЄДНАННЯ Довідник.Довідник2 ЯК Таблиця2 ПО Таблиця1.Реквізит = Таблиця2.Реквізит

У мові запитів 1С відсутній оператор для з'єднання декартового твору (CROSS JOIN). Однак, відсутність оператора не означає, що мова запитів не підтримує такого з'єднання. З'єднати таблиці за потреби можна таким чином:

ВИБРАТИ Таблиця1.Посилання ЯК Посилання З Довідник.Довідник1 ЯК Таблиця1 ЛІВОЕ З'ЄДНАННЯ Довідник.Довідник2 ЯК Таблиця2 ПО ІСТИНА

Як видно з прикладу, заданий ключ з'єднання ПО ІСТИНА, тобто кожен рядок однієї таблиці відповідає рядку іншого. Тип з'єднання (ЛІВИЙ, ПРАВИЙ, ПОВНИЙ, ВНУТРІШНІЙ) не важливий, якщо у вас є рядки в обох таблицях, але якщо в якійсь із таблиць немає рядків (пускова таблиця) – результат буде відрізнятися. Наприклад, при використанні ВНУТРІШНІЙз'єднання результат буде порожнім. При використанні ЛІВОЕ/ПРАВЕз'єднання в результаті буде або не буде даних, залежно від того, до якої таблиці ми приєднуємося - з даними чи ні. При використанні ПОВНОГОЗ'єднання дані будуть завжди (природно, лише одна таблиця, тому що в іншій порожнеча), вибір типу з'єднання залежить від конкретної прикладної задачі.

Невелика візуальна підказка, як працюють різні типиз'єднань:



ПОДІБНО.На відміну від аналогічного оператора мови SQL- LIKE, шаблон для ПОДІБНОможна задати, використовуючи тільки деякі спеціалізовані символи:

  • % (відсоток): послідовність, що містить будь-яку кількість довільних символів;
  • _ (підкреслення): один довільний символ;
  • / - наступний символ слід інтерпретувати як звичайний символ.

ПІДСУМКИ ПОаналогом SQL можна назвати оператор ROLLUP. Приклад використання оператора ПІДСУМКИ:

ВИБРАТИ Товари.Ціна ЯК Ціна, Товари.Товар ЯК Товар З Довідник.Номенклатура ЯК Товари ПІДСУМКИ СЕРЕДНЕ(Ціна) ПО Товар

Результат буде такий:

Ліжко

9833,333

Праска

Ручка

Тобто в результат додається додатковий рядок, що містить значення поля, за яким проводиться угруповання та значення функції, що агрегує.

Робота з пакетними запитами

1С дозволяє працювати із пакетами запитів. У пакетному запиті тексти запитів поділяються крапкою з комою (;). Виконання пакетного запиту 1С здійснюється послідовно. Приклад тексту пакетного запиту:

ВИБРАТИ Користувачі.Посилання ЯК Посилання, Користувачі.Батьки ЯК Батько, Користувачі.Найменування ЯК Найменування З Довідник.Користувачі ЯК Користувачі;
ВИБРАТИ ГрафікРоботи.Користувач ЯК Користувач, ГрафікРоботи.Дата ЯК Дата, ГрафікРоботи.РобочихГодинник ЯКРобочихГодин З РеєстрВідомостей.ГрафікРоботи ЯК ГрафікРоботи

Для отримання результату всіх запитів, що входять до пакета, необхідно скористатися методом об'єкта запиту "Виконати Пакет" замість "Виконати". Цей методпослідовно виконує усі запити. Результат запиту – масив результатів кожного запиту з пакета, а послідовність розташування масиві така сама, як послідовність запитів у тексті пакета.

Розглядаючи мову запитів, варто згадати про таку особливість, як віртуальні таблиці. Віртуальні таблиці відсутні у базі даних, це своєрідна обгортка, яка виконується за СУБД як запит із використанням підзапитів. Приклад запиту 1С із використанням віртуальних таблиць:

ВИБРАТИ РеєстрЗобов'язаньОбороти.Зобов'язання ЯК Зобов'язання З РегістрНакопичення.РегістрЗобов'язань.Обороти() ЯК РеєстрЗобов'язаньОбороти

Такий запит на СУБД виглядатиме так:

SEL ECT T1.Fld25931RRef FR OM (SELECT T2._Fld25931RRef AS Fld25931RRef, CAST(SUM(T2._Fld25936) AS NUMERIC(38, 8)) AS Fld25936Turnover_, CAST AS Fld25937Turnover_ FR OM dbo._AccumRgTn25938 T2 WH ERE ((T2._Fld949 = @P1)) AND ((T2._Fld25936 @P2 OR T2._Fld25937 @P3)) GROUP 2 ) AS NUMERIC(38, 8))) 0.0 OR (CAST(SUM(T2._Fld25937) AS NUMERIC(38, 8))) 0.0) T1>>>>

Видно, що не схоже на SQL, оскільки є підзапит, угруповання. Віртуальні таблиці, за великим рахунком – це «синтаксичний цукор», тобто створені загалом для зручності розробки запитів, щоб запити були компактнішими і читабельнішими.

Віртуальні таблиці є лише регістрів, але які саме віртуальні таблиці доступні регістру, можна побачити в конструкторі запитів.



При використанні віртуальних таблиць необхідно завжди давати умову відбору. В іншому випадку можуть виникнути проблеми з продуктивністю.



У тексті запиту це виглядає так:

РегістрНакопичення.РегістрЗобов'язань.Обороти(, Операція = &Операція) ЯК РегістрЗобов'язаньОбороти

Для зручності написання запитів, тобто створення текстів запитів, 1С існує конструктор, який можна викликати через контекстне меню (правою кнопкою миші):



У конструкторі запитів можна побачити повний список підтримуваних функцій та операторів мови запитів.


Конструктор запитів є дуже гнучким візуальним інструментом створення запитів будь-якої складності. Він доступний лише у режимі конфігуратора. У режимі Підприємства є так звана Консоль запитів – це зовнішня обробка, що постачається на диску ІТС. Для керованого додатка консоль запитів можна завантажити на сайті its.1c.ru.

Опис роботи в конструкторі запитів виходить за межі тематики цієї статті, тому докладно розглядатися не буде.

Причини неоптимальної роботи запитів

Нижче наведено список основних причин (але не всіх), які призводять до уповільнення виконання запиту.

  • Використання з'єднання з підзапитами

Не рекомендується виконувати з'єднання з підзапитами, підзапити необхідно замінити на тимчасові таблиці. З'єднання підзапитів може призводити до значної втрати у продуктивності, при цьому виконання запиту на різних СУБД може значно різнитися у швидкості. Швидкість виконання таких запитів також є чутливою до статистики в СУБД. Причина такої поведінки в тому, що оптимізатор СУБД не завжди коректно може визначити оптимальний план виконання запитів, оскільки оптимізатор нічого не знає про те, скільки рядків поверне підзапит після свого виконання.

  • Використання віртуальних таблиць у з'єднаннях запиту

Віртуальні таблиці лише на рівні СУБД виконуються як підзапити, тому причини такі самі, як у першому пункті.

  • Використання умов у запиті, які не підходять під існуючі індекси

Якщо в умовах запиту (в операторі ДЕабо в умовах віртуальної таблиці) використовуються поля, які не всі входять до індексу, даний запитбуде виконано з використанням SQLконструкції table scan або index scan (цілком або частково). Це позначиться не тільки на часі виконання запиту, але також буде накладено надлишкове S блокування на зайві рядки, що в свою чергу може призвести до ескалації блокувань, тобто буде заблоковано всю таблицю.

  • Використання АБО в умовах запиту

Використання логічного оператора АБОу конструкції ДЕможе також спричиняти сканування таблиці (table scan). Це відбувається через те, що СУБД не може коректно використати індекс. Замість АБОможна застосувати конструкцію ОБ'ЄДНАТИ ВСЕ.

  • Отримання даних через точку для полів складового типу

Не рекомендується отримувати значення через точку (у конструкції ВИБРАТИ, ДЕ), оскільки якщо реквізит об'єкта виявиться складовим типом, з'єднання відбуватиметься з кожною таблицею, що входить до цього складового типу. В результаті, запит на СУБД буде значно ускладнений, це може перешкодити оптимізатору у виборі коректного плану виконання запиту.



Сподобалася стаття? Поділіться їй