С того самого момента, как только «молодой» программист 1С выходит за рамки самостоятельного познания платформы, на него постепенно начинают сыпаться ограничения: «Это делай так, а не эдак!», «Так делать неправильно!», «Правильно делать так!» или «Так вообще делать нельзя!».
В то же время, если не придерживаться этих правил, сама платформа 1С продолжает работать и ошибок не выдаёт. Поэтому причина ограничений многим вдвойне непонятна.
По прошествии времени у каждого программиста появляются собственные взгляды на подобного рода утверждения. Причём эти взгляды могут не совпадать с исходными, но всегда подтверждены собственным опытом.
Давайте попробуем разобраться в навязываемых постулатах, чтобы понять – имеют они под собой основания или нет. Начнём, предполагаю, с самого популярного – с текстов запросов.
Перед тем как перейти к содержательной части, договоримся о некоторых ограничениях:
- В рамках данной статьи рассматривается некая абстрактная база данных. Без привязки к режиму работы 1С (файловый/клиент-серверный) или разработчику (MS, Oracle, …).
- Все примеры будут разбираться на основе одной таблицы с 81 строкой, которая имеет одну колонку. Эта колонка заполнена буквами русского и латинского алфавита, цифрами от 0 до 9 и двенадцатью специальными символами.
- Для удобства отображения колонка будет представлена в виде квадрата 9*9.
Постулат первый
«К реальным таблицам регистров писать запросы нельзя! Надо использовать виртуальные таблицы!»
Давайте представим, что в нашу базу данных приходит запрос – найти в таблице все необходимые символы для составления фразы «КУРСЫ-ПО-1С».
«Ха!» – подумаете вы, – «Проще простого!».
А теперь представьте себя на месте базы данных, и выполните этот запрос на нашей таблице:
Не знаю, как у вас, но у меня уже со второй строчки при последовательном чтении данных наступает примерно следующее состояние:
Оно и понятно – таблица содержит в 9 раз больше символов, чем нам необходимо. И все их приходится анализировать на соответствие запросу. Но что, если бы кто-то дал нам некий «шаблон»:
Который мы бы могли совместить с нашей таблицей и получить следующий объем данных:
Ничего лишнего – только то, что необходимо!
Примерно так же работают и виртуальные таблицы. Платформа их строит оптимальным образом с учётом заданных разработчиком параметров (в нашем случае шаблон – это аналог параметров). Именно поэтому очень важно правильно заполнять параметры виртуальных таблиц.
Так, при недостаточной параметризации, может быть построена виртуальная таблица следующего вида:
И опять придётся обрабатывать лишнюю информацию.
Обратите внимание! Если у виртуальной таблицы не указаны параметры, то запрос будет выполнен к реальной таблице базы данных.
Получается, что утверждение «К реальным таблицам регистров писать запросы нельзя! Надо использовать виртуальные таблицы!» верно в том случае, когда представляется возможным использование виртуальных таблиц, и эффективно работает, если правильно заполнены параметры виртуальной таблицы.
Постулат второй
«Используй индексирование!»
Мы уже попробовали поиск путём последовательного чтения каждого элемента нашей таблицы. А что, если произвести некоторую сегментацию нашей таблицы? Улучшит ли это поиск результата?
Давайте проверим это следующим образом: буквы русского алфавита разместим на жёлтом фоне, цифры – на зелёном, а специальные символы – на голубом. Буквы латинского алфавита при этом оставим без изменений:
Теперь при поиске нужных нам символов мы анализируем только ячейки с определённым цветом фона. Это позволяет сократить зону поиска и объём обрабатываемой информации, что положительно влияет на скорость выдачи результата.
Аналогично работают и индексы в «1С:Предприятие» – вся информация делится на сегменты по определённым признакам и эта сегментация помещается в отдельную таблицу.
При необходимости осуществления поиска по индексированному полю платформа вначале производит оптимизированную выборку по таблице индексов, а затем переходит к обработке информации из таблицы с данными тех строк, которые были найдены по индексам.
Вся эта информация помещается в отдельную самостоятельную таблицу базы данных и количество записей в ней может превышать количество записей в исходной таблице в разы.
Поэтому настройка индексов оправдана только в том случае, когда эффект от их использования выше, чем затраты на создание и обслуживание отдельной таблицы базы данных.
Получается, что утверждение «Используй индексирование!» имеет обоснование. Но также имеет много нюансов, которые необходимо учитывать. Это и объём индексируемых данных, и взаимодействие с другими таблицами, и вид используемой базы данных.
Например, если обрабатываемая таблица имеет небольшой объём данных, то индексирование в этом случае будет негативно влиять на быстродействие.
Постулат третий
«Не получай лишние поля!»
В отличие от предыдущих двух утверждений, с этим не поспоришь. Просто не бывает так, когда какое-то лишнее поле, полученное в результате запроса, положительно влияло бы на функционирование 1С.
Уверен, что сейчас многие готовы крикнуть в один голос – «Автор, ты пишешь прописную истину! Зачем?!». Но постойте! Наверняка в вашем опыте есть случаи проведения рефакторинга кода запроса? А теперь признайтесь – хоть раз вы говорили себе что-то вроде «не буду-ка я трогать это поле, вдруг оно где-то используется…»?
И тут начинается многообразие факторов, негативно влияющих на производительность. От банального увеличения объема результата запроса до вложенных запросов и лишних соединений.
Поэтому всегда анализируйте – какую информацию вам необходимо получить для решения конкретной задачи, и не рискуйте ради мысли «а вдруг пригодится».
Вместо заключения
В статье описана лишь малая толика того, с чем сталкивается каждый программист 1С по мере увеличения опыта. И каждый решает самостоятельно, как поступать с новыми утверждениями: использовать как аксиому, разобраться в вопросе и принимать взвешенное решение или продолжать делать так, будто ничего и не слышал.
Надеюсь, данный материал поможет кому-то приподняться на очередную ступень, а кому-то поменять свой взгляд на «входящие догмы».
P.S. А с какими «постулатами» сталкивались Вы? Пишите в комментариях – обсудим! :)
Об авторе
PDF-версия статьи для участников группы ВКонтакте
Мы ведем группу ВКонтакте – http://vk.com/kursypo1c.
Если Вы еще не вступили в нее – сделайте это сейчас, и в блоке ниже (на этой странице) появятся ссылки на скачивание материалов.
Вы можете скачать эту статью в формате PDF по следующей ссылке: Ссылка доступна для зарегистрированных пользователей)
Ну я не знаю.. Шо ругаются? А мне понравилось)) Я тех.литературу читать не люблю. Засыпаю на второй строчке. А вот так вот на пальцах – очень круто! Я много про виртуальные таблицы читала, и, кажется, даже понимала, но только теперь поверила)) и главное – прочно ЗАПОМНИЛА. Побольше таких статей! Спасибо от души!
“Получай данные из запроса через одну точку” :)
За рукописные рисунки – спасибо, это оригинально. И, местами даже легче воспринимается.
Я раньше так же думал: есть виртуальная таблица – надо обращаться к ней, но для виртуальных таблиц Оборотов регистров накопления Остатков я все же думаю никакой разницы нет.
“Обратите внимание! Если у виртуальной таблицы не указаны параметры, то запрос будет выполнен к реальной таблице базы данных. Источник: ©Курсы-по-1С.рф”
Вот это вообще непонятно. С чего вдруг? Я прям аж засомневалась, решила проверить. Создала пустую базу (клиент-серверную), два справочника Склад и Номенклатура, документ Приходная накладная, Расходная накладная и Регистр накопления (Остатки на складе).
По регистру получили две таблицы:
AccumRg18 – таблица движений
и AccumRgT22 – таблица итогов
Простенький запрос:
| ОстаткиНаСкладеОстатки.Номенклатура КАК Номенклатура,
| ОстаткиНаСкладеОстатки.Склад КАК Склад,
| ОстаткиНаСкладеОстатки.КоличествоОстаток КАК КоличествоОстаток
|ИЗ
| РегистрНакопления.ОстаткиНаСкладе.Остатки КАК ОстаткиНаСкладеОстатки";
Зашла в SQL Profiler, сделала трассировку, посмотрела план запроса:
T1.Fld19RRef,
T1.Fld20RRef,
T1.Fld21Balance_
FROM (SELECT
T2._Fld20RRef AS Fld20RRef,
T2._Fld19RRef AS Fld19RRef,
T2._Fld21 AS Fld21Balance_
FROM dbo._AccumRgT22 T2
WHERE T2._Period = @P1 AND (T2._Fld21 <> @P2) AND (T2._Fld21 <> @P3)) T1',N'@P1 datetime2(3),@P2 numeric(10),@P3 numeric(10)','5999-11-01 00:00:00',0,0
AccumRgT22 это таблица ИТОГОВ для регистра. Всё ок, никаких при этом параметров в запросе как вы видите нет, ни отборов по складу, ни отборов по номенклатуре.
Согласно же вашей логике, я должна переписывать запрос выбирая данные из таблицы движений и суммируя все приходы и расходы, чтобы получить остатки (т.е. по таблице AccumRg18). При этом перед тем как засуммировать, т.е. сгруппировать данные, SQL мне шуранет фактически весь объем данных по регистру в TempDB, а потом уже из нее считает их дабы выполнить заветное group by. Т.е. отожраное дисковое пространство и затраты на процесс записи данных из AccumRgT18 в TempDB и блокировки к TempDB в расчет не берем, а просто бегаем ребутим сервак каждые 2 часа?
katrin, добрый комментарий! Спасибо за повод для дискуссий :) Для начала поясню «Обратите внимание! Если у виртуальной таблицы не указаны параметры, то запрос будет выполнен к реальной таблице базы данных. Источник: ©Курсы-по-1С.рф».
Ни в коем случае это не призыв писать вместо «запросов без параметров к виртуальным таблицам» «запросы к реальным таблицам». Наоборот, это призыв максимально эффективно использовать параметры виртуальных таблиц. Как уже отмечалось ниже в комментариях – «без установки параметров виртуальной таблицы не будут использованы преимущества по построению наиболее оптимального запроса к базе данных, которые предоставляет платформа». Если Ваш пример спроецировать на реальную работу реальных людей, то крайне редко в один момент нужны остатки по всем товарам в разрезе всех складов. Поэтому необходимо предусматривать возможность отборов. И тут думаю Вы согласитесь с тем, что запрос
T1.Fld28RRef,
T1.Fld27RRef,
T1.Fld29Balance_,
T1.Fld30Balance_
FROM (SELECT
T2._Fld28RRef AS Fld28RRef,
T2._Fld27RRef AS Fld27RRef,
CAST(SUM(T2._Fld29) AS NUMERIC(33, 8)) AS Fld29Balance_,
CAST(SUM(T2._Fld30) AS NUMERIC(33, 8)) AS Fld30Balance_
FROM dbo._AccumRgT31 T2
WHERE T2._Period = @P1 AND ((T2._Fld27RRef = @P2)) AND (T2._Fld29 @P3 OR T2._Fld30 @P4) AND (T2._Fld29 @P5 OR T2._Fld30 @P6)
GROUP BY T2._Fld28RRef,
T2._Fld27RRef
HAVING (CAST(SUM(T2._Fld29) AS NUMERIC(33, 8))) 0.0 OR (CAST(SUM(T2._Fld30) AS NUMERIC(33, 8))) 0.0) T1',N'@P1 datetime2(3),@P2 varbinary(16),@P3 numeric(10),@P4 numeric(10),@P5 numeric(10),@P6 numeric(10)','5999-11-01 00:00:00',0x80D560EB69FE750311E73B006A13AE70,0,0,0,0»
будет работать лучше, чем
T1.Fld28RRef,
T1.Fld27RRef,
T1.Fld29Balance_,
T1.Fld30Balance_
FROM (SELECT
T2._Fld28RRef AS Fld28RRef,
T2._Fld27RRef AS Fld27RRef,
CAST(SUM(T2._Fld29) AS NUMERIC(33, 8)) AS Fld29Balance_,
CAST(SUM(T2._Fld30) AS NUMERIC(33, 8)) AS Fld30Balance_
FROM dbo._AccumRgT31 T2
WHERE T2._Period = @P1 AND (T2._Fld29 @P2 OR T2._Fld30 @P3) AND (T2._Fld29 @P4 OR T2._Fld30 @P5)
GROUP BY T2._Fld28RRef,
T2._Fld27RRef
HAVING (CAST(SUM(T2._Fld29) AS NUMERIC(33, 8))) 0.0 OR (CAST(SUM(T2._Fld30) AS NUMERIC(33, 8))) 0.0) T1
WHERE (T1.Fld27RRef = @P6)',N'@P1 datetime2(3),@P2 numeric(10),@P3 numeric(10),@P4 numeric(10),@P5 numeric(10),@P6 varbinary(16)','5999-11-01 00:00:00',0,0,0,0,0x80D560EB69FE750311E73B006A13AE70»
И это, если говорить только про получение остатков по регистрам накоплений или про срезы по регистрам сведений. Запросы же без параметров к остальным видам виртуальных таблиц очень редко (на мой взгляд) имеет здравый смысл.
Интересно то, что данный «кусочек статьи» уже был предметом дискуссий, но в обраном направлении. Там было выражено несогласие с тем, что что-то получается не из реальных таблиц – ведь кроме как реальных в базе данных других таблиц не существует! =)
И у меня возник вопрос – что участники сообщества 1С-ников понимают под термином «Виртуальная таблица» в запросе 1С? katrin, как на него ответили бы Вы?
Основная догма про виртуальные таблицы регистров: “Если запрос работает медленнее чем с реальными таблицами, проверь на какую дату рассчитаны итоги и рассчитаны ли вообще!”. Да проверь настройку обновления статистики (если это клиент-серверная конфа).
Просто наглядно внятно и понятно
Благодарность Автору!
Ждем продолжения и еще статей.
Павел, привет!
Очередной “рукописный” шедевр. :)
Кирилл, спасибо :) Но до шедевра ещё далеко)
Ещё одна догма:
обычный интерфейс быстрее управляемого.
Да, это миф, на самом деле обычный интерфейс НАМНОГО быстрее управляемого..
познавательная статья, спасибо!
А рисунки базы сделали мой день сегодня! За них отдельная благодарность! :)
Картинки огонь. Особенно база после последовательного чтения :)
Автор красавчек! Молодец, всё очень доходчиво и понятно!
Цитата “Получается, что утверждение «К реальным таблицам регистров писать запросы нельзя! Надо использовать виртуальные таблицы!» верно в том случае, когда представляется возможным использование виртуальных таблиц, и эффективно работает, если правильно заполнены параметры виртуальной таблицы.” Как заполнять параметры правильно вообще ничего не сказано, можно свести к мысли если делать правильно то будет хорошо, а вот если не правильно то плохо. Для меня эта статья зря потраченное время.
Дмитрий, спасибо за уделённое статье время! Спасибо за комментарий! :)
Я бы добавил еще постулат:
Если поле регистра имеет составной тип и в запросе используется конкретный один тип для этого поля – используй функцию ВЫРАЗИТЬ().
Александр, отлично! Есть такое! :)
еще не лишним будет для полей с неограниченной длиной тоже делать выразить( как строка(50)) хотя бы. А для перечислений использовать Представление()
DoCaru, всё верно! Только Представление() лучше использовать не только для перечислений, а для всех ссылочных полей, которые планируется выводить в виде текста, например в табличный или текстовый документ.
Не точный постулат. Выразить() нужно использовать если ты получаешь данные через точку от составного поля, например, дата документа прих.накл. Иначе, если поле состоит из 120 типов, ты будешь делать 120 левых соединений со всеми вытекающими тормозами.
в каждой компании есть свои правила (традиции):
– наименование переменных/процедур/функций (например, СотрудникСтрока или СотрудникСсылка);
– наименование метаданных (например, Рарус добавляет префикс «РАР_» к создаваемым метаданным (реквизиты, документы, регистры и прочее);
– определЁнные требования к стилю написания кода (например, немало программеров пишут код как попало – то есть в каждой строчке, без пробелов перед скобками и без пробелов после запятых, табуляцию не приемлют. если бы не автоотступы для циклов, условий и прочего, то они бы писали вообще всЁ в один столбик. такой код очень сложно читать).
лично я в мир 1С пришЁл из мира С++, в который в свою очередь пришЁл из мира Асма. я активно применяю в написании кода 1С так называемую «Венгерскую нотацию», отделяю блоки кода пустыми строками, использую области (#Область … #КонецОбласти) для группировки нескольких блоков кода.
хотелось бы, чтобы у объекта метаданных было несколько модулей форм, а то бывают такие документы с 100500 обработчиками событий, что коду края и конца не видно. а так добавил бы несколько модулей форм: в одном модуле обработчики самой формы, в другой модуле – обработчики реквизитов шапки, в третьей – обработчики одной табличной части (далее ТЧ), в четвЁртой – обработчики другой ТЧ и т. д. если количество обработчиков всех ТЧ невелико, что их можно разместить и в одном модуле формы.
считаю, что это бы упростило разбор больших документов.
Обратите внимание – 1С в последних релизах выносит все в общие модули из форм документов. В самих формах только вызовы и обработчики команд.
Плюсы пример для всех патсулатов
Snouphruh, а вы закиньте в головной 1С свои идеи!
Вот области они уже ввели- насколько удобней стало. Все что хорошо структурировано – помогает уменьшить ошибки и увеличить кпд.
Лично я бы Вам первая спасибо сказала за неск. модулей формы со своим назначением, лучше определяемым самим программистом
Колеги, 1С давно следует написать свою СУБД, которая правльно ,s реагировала на вызовы платформы, работла бы правьно с вьюшками, и вообще бы все претензии были бы к 1С, а не …
:) Это вроде того, чтобы сконструировать велосипед надо изобрести свое колесо, например квадратное… Тягаться с СУБД которые использует 1С, для фирмы 1С просто не реально и нет ни какой необходимости.
Если СУБД будет работать также как платформа то лучше не надо. Насчёт ответственности 1с перед клиентами очень интересный вопрос.К примеру я в феврале не поленился и отправил специфический баг. Письмо приняли. И что дальше? А дальше стандартный, очень вежливый ответ, ваше обращение находится на рассмотрении у разработчиков. Сроки не регламентируются. Ждите. Возникает вопрос – что дальше? Одно радует, есть стабильность в отсутсвии ответа.
Был один интересный случай, связанный с виртуальными таблицами периодического регистра сведений – Цена номенклатуры. Запрос
Выбрать
Рег.Номенклатура,
Рег.ВидЦены,
Рег.Цена
ИЗ
РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&ДатаСреза, Номенклатура = &Номенклатура И ВидЦены = &ВидЦены)
выполнялся подозрительно долго, несколько секунд. Платформа была еще 8.2, возможно в новых релизах это исправлено. Для выяснения причин запрос был переписан на выполнение запроса к реальной таблице регистра: сначала создание временной таблицы с получением максимального периода, который меньше либо равен дате среза с отбором по измерениям, что по идее соответствует виртуальной таблице и затем соединение таблицы регистра с этой временной таблицей по измерениям и этому максимальному периоду, что в итоге дает аналогичный результат, но время выполнения запроса при этом < 0.5 сек. Видимо дело в том, что параметр ДатаСреза может быть и датой и моментом времени и границей, из-за чего возможна генерация платформой неоптимального запроса. Так что не все так однозначно))
lexasan, можно уточнить – причина была как-то расследована? Или всё же только предположена? :)
Столкнулся с подобной проблемой на 8.3.8. Запрос к срезу последних выполняется долго (>300 мс при получении записи по одной строке), переписанный запрос с временной таблицей выполняется в разы быстрее (примерно 20мс создание вр.т, 25 мс построение среза и 1 мс удаление вр.таблицы). Анализ запроса в Profiler указывает на примерное соответствие запросов, полученных обоими способами, но работа с виртуальной таблицей почему то медленнее. В результате причины замедления так и не были выявлены и теперь запрос НЕ использует срез поледних.
Snake, интересная информация. Спасибо!
А я вот давно хотел узнать: есть ли какая то разница между запросом в виртуальную таблицу с периодичностью по регистратору и запросом в реальную таблицу?
Игорь, разница есть. Как минимум, у одного регистратора может быть несколько движений по этому регистру. А ещё не забываем про другие параметры виртуальной таблицы, правильное использование которых положительно влияет на быстродействии [в большинстве случаев :) ]
“Как минимум, у одного регистратора может быть несколько движений по этому регистру”… это понятно. я неточно описал свое условие. Однако Ваша статья побудила меня протестировать разницу. Написал два простых запроса по регистру Продажи: 1. Вывод периода, регистратора и номенклатуры по оборотному регистру с периодичностью по регистратору 2. Вывод периода, регистратора и номенклатуры по обычному регистру. Результат по времени одинаковый.
Потом начал добавлять в первый запрос условия в параметры виртуальной таблицы, во второй те же в секцию ГДЕ.
Разницу увидел когда задал много условий, но добиться разницы по времени больше 1 секунды так и не удалось и то она появилась, когда условие задал через точку (Контрагент.ГоловнойКонтрагент=).
Игорь, я очень рад, что моя статья побуждает пытливые умы к действию! :) Спасибо Вам!
Тут в комментариях уже отмечали, что увеличение производительности при запросах к виртуальным таблицам оборотов зависит от использования таблицы итогов. Поэтому только условиями тестировать не достаточно. Вообще, лучше анализировать не только общее время выполнения запроса, но и план запроса чтобы понимать – на что приходится основная нагрузка. Подробно об этом можно узнать из курсов по оптимизации, например http://курсы-по-1с.рф/1c-v8/development-optimize-queries/
В копилку догм: “Файловая версия только для разработки/тестирования и ларьков из 1-2 пользователей”. Для поддержки догмы даже выпущен специальный продукт “Мини-сервер на 5 пользователей”. На деле в файловых базах УПП (свят-свят) объемами от 5 до 20 Гбайт спокойно работали по 15-20 пользователей одновременно (на терминальном сервере). При условии, что это не транзакционная оперативная работа. В моем случае это были просто большие бухгалтерии, где УПП использовалась как комплексная для посмертного фискального учета – бухучет+зарплата+развитые возможности распределения затрат. Для бухгалтера совершенно не критично, если пару раз за день выскочит ошибка блокировки таблицы при проведении документа – лишний повод съесть дополнительную конфетку или яблочко за время ожидания.
Подтверждаю про УПП в файловом варианте 15 пользователей, база 20 ГБ, а бухгалтерия и подавно
Положительный момент в работе бухгалтера – надежда на такие “ошибки” что бы отвлечься от рутины
Читаю статьи Павла Ванина ради одних только картинок. Про серверный вызов, кажется, он же писал?
Точно :)
“не бывает так, когда какое-то лишнее поле, полученное в результате запроса, положительно влияло бы на функционирование 1С”
Бывает, и достаточно часто: вытянув запросом ссылку, начинаем выводить её в отчёт и получаем гору запросов на получение предоставления этой ссылки. Тут надо хорошо понимать что является действительно лишним полем, а что нет. Убрав лишнее представление из запроса, новичок может многократно замедлить весь механизм.
Sen, всё правильно – для каждой задачи необходимо правильно определять требуемые поля и получать только их. Если выборка делается с целью вывода в отчет, то представление не является лишним полем. Если с целью программной обработки данных, то получение этого поля будет излишним.
Павел, Прекрасная статья!
Александр, Спасибо!
Первый постулат очень спорный. На виртуальных таблицах свет клином не сошелся. На моей практикке встречаются задачи, которые эффективней решаются обращением к реальным таблицам.
Для примера попробуйте в большой базе БП (от 100 млн проводок) получить дату последней амортизации по каждому ОС. Виртуальная таблица Обороты позволяет решить эту задачу, но гораздо менее эффективно, чем соединение реальных таблиц регистра.
Не совсем удачный пример. :) Виртуальные таблицы в регистре накопления используются для получения остатков и оборотов. В Вашем случае, надо последнюю получить запись по определенному алгоритму, но ни как ни остаток или оборот и обращаться к виртуальной таблице в таком случае действительно было бы странным. Но есть другой пример, например получение оборотов по регистру накопления остатков или по оборотному регистру накопления за период в котором нет ни одного полного месяца, в этом случае виртуальная таблица не даст выигрыша, поскольку не будет обращаться к таблице итогов.
Доброго всем дня. В процессе работы сталкиваюсь с разработчиками 1с. И вот подумал пойти на курсы программирования. Но пока только подумал, Т.к. очень многое не понятно мне (все эти программные термины). А в этой статье так (даже для меня, ничего не смыслящего в программировании) все хорошо изложено и с такими понятными картинками. Спасибо автору.
Отличная статья.
Предложение – может, использовать слово “разработчик 1С”, а не “программист 1С”?
Максим, спасибо! Возьму на заметку.
Конфигурировщик 1С! =)
П.С. Я тоже стараюсь избегать термина “программирование” по отношению к 1С. =)
Добрый день! Ещё одна догма – “запросы в циклах”. Но ведь можно утверждать, что “умная” СУБД скомпилировав запрос, оставит его в памяти и превратит в параметризованный запрос. А параметризованный запрос – обыденная вещь при работе с данными.
Если не учитывать большие накладные расходы на вызов сервера SQL
Добрый день!
Картинки как всегда порадовали, материал бесспорно полезен.
если можно маленькое замечание:
Утверждение “Обратите внимание! Если у виртуальной таблицы не указаны параметры, то запрос будет выполнен к реальной таблице базы данных.” наводит на мысль что если использовать параметры виртуальной таблицы, то запрос не будет выполнен к реальным таблицам. По моему это ересь. :) Других таблиц в базе данных нет.
Андрей, несомненно данные будут получены из реальных таблиц! А если “копнуть глубже”, то вообще всё получается из единиц и нолей, и вовсе “ложки не существует” (с)!
В данном контексте подразумевается, что без установки параметров виртуальной таблицы не будут использованы преимущества по построению наиболее оптимального запроса к базе данных, которые предоставляет платформа.
Тут как в анекдоте – “и ты тоже прав” (с)
Люди которые это понимают так глубоко не являются целевой аудиторией статьи. Верно?
Люди которые хотят что-то почерпнуть и будут обдумывать Ваши предложения могут прийти к неверному выводу. Это все что я хотел сказать.
Почему же не являются? :) Благодаря таким людям в комментариях как правило наблюдается конструктивное обсуждение темы. А те, кто хотят почерпнуть что-то, прочитают и комментарии тоже :)
Спасибо Вам за участие!
Андрей, на первые 2-10 лет программирования целевой аудитории хватит и такого вывода – использование параметров виртуальной таблицы будет гораздо лучше, чем ставить их в секцию ГДЕ.
А потом копнут глубже и всё будет хорошо:-)
2-10 лет? 2 года еще туда-сюда, но за 10 лет программирования не озаботиться вопросом что такое виртуальные таблицы и как работают это имхо перебор.
Ну почему же перебор? 2-5 лет пользователи ничего не заметят, а к 10 база имеет шансы вырасти настолько что отчет который формировался за 30 секунд будет формироваться 3 часа. И тогда точно придется думать в чем же дело. Имел “счастье” переделывать такой отчет.
Это если сидеть на мягком месте и не пытаться себя развивать. Ps запрос в 30 сек уже должен заставить задуматься. Или запрос кривой или структура данных.
Где то читал что на 2016 SQL это уже будет не так критично. В новом сервере существенно переработан оптимизатор запросов, и позволяет транслировать условия Where во вложенные запросы. Фактически это будет перенос из конструкции Где в параметры запроса виртуальной таблицы. Возможно ошибаюсь, но информация интересная. Пока проверить возможности нет.
Так вроде и на более ранних версиях SQL, по крайней мере 2012-2014, оптимизатор на уровне плана запроса это отрабатывает. Но есть несколько но!
-Если запрос сложный, далеко не факт что именно так отработает.
-Зачем просить СУБД лишний раз додумывать?
-Может использоваться не такая умная СУБД как MS SQL Server последних версий.
Справедливо для ВТ только РН и РБ. С РС все более интересно…
Честно говоря, мне тоже кажется, что тема про виртуальные таблицы скорее вводит в заблуждение, чем учит. Тут надо либо вдаваться в детали как виртуальные таблицы превращаются в реальные, либо и не поднимать вопрос. Ну или хотя бы вкратце сказать, что виртуальная таблица примерно превращается в группировку выборки из реальной таблицы, где параметры накладывают отбор до группировки, что повышает быстродействие. Но опять же есть куча нюансов из-за которых может быть выгоднее смотреть чистый регистр.
Это тема для рассмотрения в курсе по оптимизации а не для новичков. Мне, в свое время, хватило фразы: “на экзамене за такое просто выгоняют”. Вот так я начал внимательнее смотреть на параметры запросов к виртуальным таблицам. :)
Да вот мне как-то непонятно в чем смысл данной статьи. Если б просто перечислялись догмы, которые надо выполнять не задавая вопросов (“за это выгоняют”) – это понятно. Если полноценный разбор причин откуда растут ноги этих догм – это тоже понятно. Но вот что-то среднее по типу “пальцы в розетку нельзя совать, потому что электроны будут бить отрицательными зарядами” как-то не очень.
Тогда стоит именно так и сформулировать. В текущем прочтении статьи складывается впечатление, что при отсутствии параметров никакой магии нет. Что легко опровергается сравнением выдачи любых физических таблиц регистров и выдач с их виртуальных дополнений без указания параметров (для РС срезы построятся на текущую дату, в РН остатки тоже на текущую даты, а в оборотах не будет никаких дат и только итоговые цифры свернутые по измерениям за весь период учета; про регистры бухгалтерии и расчета даже говорить не чего, настолько в глаза бросается их различие).
Дмитрий, спасибо за открытость!) Постараюсь учесть все замечания в будущих работах.