Related Posts
- Восстановление последовательности документов при закрытии месяца в Бухгалтерия 3.0 не завершается
- Заполнение табличных частей
- Формирование сводных актов выполненных работ
- Ввод поступления в переработку на основании передачи сырья (между организациями)
- Конспект по установке сервера 1С на linux
- Получение имени компьютера и его IP локально и в терминале
В принципе интересно написано)
Спасибо, написано очень доступно для понимания
написано живенько, для новичков вполне подойдёт
я тоже пытался раскрыть тему скорости соединенийhttp://infostart.ru/public/534444/
Но что-то пошло не так )))
Надеюсь, Андрею повезет больше. Удачи.
Зачет!
Самое главное упущено:
Большая часть операторов плана работает построчно, т.е. для того, чтобы вернуть первую строку, им достаточно получить от нижестоящего оператора одну строку, подходящую по условиям.
Однако некоторым операторам для возврата первой строки необходимы все строки, возвращаемые предыдущим оператором. Это Sort (Что логично, пока мы не получим последнюю строку, мы не можем завершить сортировку), это для одного из наборов строк — Hash join и т.п.
Т.е. когда мы видим оператор Sort в запросе динамического списка — можно начинать ругаться не глядя 🙂
В последних версиях платформы, кстати, добавили ограничение на использование полей для сортировки списков. Вот именно по этой причине.
А вот неплохой доклад по теме:
https://www.youtube.com/watch?v=4yHc8-Idf-w
(6)отчего же упущено? Написано же: на входе одно множество, на выходе — другое. Сортировка сюда подходит.
Мне кажется, для 1сника будет интересен также ответ на вопрос: что происходит в субд, когда он жмет F5 (или какую-то другую команду на выполнение) в среде исполнения запроса. По MS SQL такой инфы с нуля я не находил. По PostgreSQL есть шикардосная статья:Путешествие запроса Select через внутренности Постгреса
Спасибо, как раз хотел объяснить дочери (4 класс) реляционные базы, она интересовалась, текст как основа подойдет. «Быстродействие тетеньки из регистратуры» это пять.
Статью не читал, но имею сказать по существу) «Наверное, каждый 1С-ник задавался вопросом «что быстрее, соединение или условие в ГДЕ?» или, например, «сделать вложенный запрос или поставить оператор В()»?» — лучше чем проверка разных вариантов практически, ничего нет. Один и тот же запрос на разных базах может работать по разному. Например, в одной базе номенклатуры 1000, а в другой 100000. И хорошо работающий запрос из базы с небольшой номенклатурой будет дико тормозить в другой базе. Но если вы не писатель типовых программ или отраслевых решений, то достаточно замеров времени выполнения на вашей конкретной базе. А для понимания работы запросов советую курсы. Они быстрее помогут разобраться новичкам, как писать текст запросов, чем копание в планах запроса. Это совет, но ни в коем случае не отрицательный отзыв на статью!
(11)
Вот это я прямо в рамочку поставлю!
Я, даже как знакомый с планами запросов, прочитал с удовольствием и открыл для себя даже новое (я например думал что СУБД гораздо умнее).
Вобщем очень хорошо информация ложится в голову с такими простыми примерами.
Автору спасибо!
(0) Очередная отличная юморная статья от владельца статуэтки Инфостарт 🙂
Хорошая статья, но кажется не законченной, так как всё равно нет ответа на поставленной вопрос:
(8) вопрос в том, сколько строк будет прочитано для получения множества, ограниченного TOP.
(15) Ответа на этот вопрос не существует: сам вопрос поставлен некорректно.
Кстати, в случае достаточно простых условий план для этих вариантов будет один и тот же.
спасибо, ждем-с продолжения
(12) 1) Идея была в другом. Сначала набрать основу, как правильно писать запросы, а потом лезть внутрь SQL. Набрать основу проще всего: 1) на курсах 2) читая статьи на ИТС или спецресурсах 3) спрашивая на форумах. Поэтому я предложил сначала получить базу на курсах.
2) Я могу предположить, что план запросов в разных базах будет разным, даже в зависимости от наполнения таблиц, статистики и прочего. И план запроса может также ввести в заблуждение, как и замер времени на пустой базе.
3) Для простых случаев не вижу ничего плохого в использовании замера времени. Вот когда замеры вопроса не решают, тогда да. Тогда и КИП лишним не будет.
(14) это не статуэтка, а параллелепипед )
Аггрегация
Дочитал до nested loops, пришла мысль, что автор недопонимает, но осилил дочитать до конца, после чего понял, что нужно дочитывать до конца.
(22) прочитал комментарий до конца. Два раза, после чего, так и не понял, это была критика или одобрение?
(23)
Как сказала наш тренер по публичным выступлениям и работе с аудиторией, что если чувства после реплики противоречивые, то однозначно вами манипулируют!
Какой кошмар написан про индексы, ведь полно статей на инфостарте, где все правильно расписано.
«Пользователь захочет записать в середину индекса» придётся всё двигать? Какой ужас.
Еще в начале статьи написано, что дальше массивов никуда не ушли. А как же STL, как же списки, очереди?
Индексы хранятся в виде бинарных деревьев: во первых хранятся блоками, где заранее предусмотрено место под вставку, во вторых передвинуть блок в дереве не проблема, проблема — сбалансировать дерево.
(25) а вам не пришло в голову, что это необходимое упрощение?
Ну и про STL посмеялся, спасибо. На дрсуге подумайте, как реализованы ваши списки и очереди.
Начало статьи было хорошее. Планируется продолжение? Осталось ощущение недосказанного, оборванного вдруг…
(26) Может Вам лучше всё-таки узнать как утроены деревья, а не смеяться на тем чего не знаете? Я Вам конкретно указал, что не существует выдуманной Вами проблемы вставки элемента в середину дерева. Списки, деревья, каталоги, очереди — это уже совсем не массивы, про которые Вам рассказали в школе. Стандартная библиотека шаблонов, довольно, кардинально изменила подход в работе с данными.
Необходимое упрощение? Т.е. эта такая мелочь, что именно с помощью индексов достигается масштабируемость?
Лично я не вижу смысла заглядывать в план построения запроса, не беспокоитесь заглядывал, просто не вижу в этом никакого смысла, когда задачу можно решить куда более простым путём.
Консоль запросов — умеет замерять затраты на отдельные части запроса. Видим, в каком месте проблема, а проблема всегда в одном — не используются индексы. И разбираемся почему не используются, как правило, запрос написан так, что SQL или другой СУБД слишком сложно разобрать запрос. Проблема решается, как правило, дроблением огромного запроса, на несколько мелких.
Также нужно понимать, какие индексы строит 1С, что местами не очень очевидно, например в случае с периодическими регистрами сведений, мало того, концепция построения индекса для периодического регистра сведений различная, для различный версий программных файлов.
Подытожим:
Какой смысл заглядывать в план построения запроса? Чтобы найти узкое место? Так его можно найти намного проще.
В статье написано, что вот мол на маленькой базе всё нормально, а при большом количестве данных начинает всё тормозить. Т.е. заранее сможете по плану построения запроса сделать прогнозы? Так это враньё, т.к. лишний раз СУБД не будет использовать индексные файлы, и план построения запроса будет зависеть от состояния БД, мало того ещё и от статистики будет зависеть.
(26)
Да собственно в чем проблема, долго пример списка привести, все остальные объекты (деревья, очереди, словари и т.д.) подобны списку.
Для списка мы храним ссылку на первый элемент, в случае пустого списка храним NULL.
Каждый элемент, хранит
— Ссылку на данные.
— Ссылку на следующий элемент списка. Последний элемент хранит NULL.
В чём проблема вставить элемент в середину списка? Сколько это займёт времени?
(30)
Всегда интересовался, как в таком списке найти некий элемент X. Приведите пример его поиска, отличного от scan.
Спасибо, понравилось!
(31)
На Си со времен института не писал, могу ошибаться в названии объектов.
Создаём MultiSet, в этот объект добавляем ключ (реквизит по которому будем осуществлять поиск), и ссылку на элемент списка. Собственно индексы подобным образом и работают.
А поиск по MultiSet очень быстро отработает.
Говоря языком 1С, то же самое что добавить индекс к таблице значений.
(33)
Тут есть одна проблема: когда мы добавляем индекс, то нам нужно при вставке каждый раз этот индекс расщеплять на часть до и часть после. Вот есть у Вас тот мультисет — это просто список с хештаблицей к элементам, полагаю. Вот добавили вы его — и вроде все хорошо, добавился элемент. Но дальше вам нужно этот индекс сохранить — это запись. Допустим у Вас есть какая-то недозанятая страница и Вы просто в нее пишите. Если вставлять подряд кучу данных, то однажды незанятые страницы закончатся и нужно будет какую-то страницу расщеплять на две, в итоге будут две наполовину пустые страницы. Но при этом в саму таблицу Вы вставляете элементы в конец и не особо паритесь с поиском, ибо есть индекс. Но когда есть кластерный индекс, то при каждой вставке будет искаться свободная страница для самой таблицы, и если ее нет — она будет расщепляться, ибо кластерный индекс задает упорядочивание самой таблицы.
Дальше Вам надо что-то по кластерному индексу найти. В итоге это уже или скан, что нехорошо, или сик. Второе — это поиск в кластерном индексе (читай — в таблице) по полям этой таблицы, которые уже лежат в неком списке со ссылкой на элементы, которые больше, и на элементы, которые меньше —B-TREE . Так вот и индекс в виде такого дерева хранится, а не в виде мультисета (если, конечно, это обычный индекс, который юзается в 1С, а не gist/hash-индексы, которые в 1С не юзаются).
(29)
Я такого не писал. Я писал о невыдуманной мной проблеме вставки в середину файла. И написал, как она решается. Кроме того, сбалансированные деревья я также упомянул.
И это необходимое для данного уровня упрощение. Основной тезис которого, что вставка в середину индекса — дорогая операция, а индексы — занимают место, поскольку это не какой-то волшебный булев признак, а полноценная сущность, являющаяся проекцией данных самой таблицы.
Поверьте, довольно большой процент «программистов 1С» на собеседованиях не знает даже этого. У них есть мантра «включить индексирование», а что это и зачем, и как вообще выглядит — не знают.
(30) проблема вставки в середину списка заключается в поиске середины списка. Мне неизвестно иного способа, кроме сканирования списка.
(34)
Неверно предполагаете, мультисет — это дерево, а дерево это есть частный случай списка.
Структура списка:
— Ссылка на данные
— Следующий элемент
Структура дерева :
— Ссылка на данные
— Левая ветвь
— Правая ветвь
Поэтому я никак не могу вас понять почему в список быстро вставлять, а в дерево (в индекс) долго. Дерево — это частный случай списка.
Не вижу никакой проблемы вставлять элементы в дерево. Вы каждый упоминаете кластерный индекс, но его используют далеко не везде и не всегда.
А я пишу про обычное дерево (обычный индекс), и я не вижу никаких проблем в добавление нового элемента в дерево. Да, каждый раз перед записью будет происходить поиск нужного узла дерева, но это не так долго, для глубины дерева в 20 элементов это уже 1 млн значений, и чем больше глубина тем больше разница, т.е. при глубине дерева 30 элементов это уже 1 млрд. значений.
Да, при количестве элементов в 1 млн, при каждой записи будет осуществлен перебор до 20 элементов (может и с первого раза повезет), но 20 элементов перебрать всяко лучше чем 1 млн.
(37) я не совсем понимаю, с чем конкретно вы пытаетесь спорить, и в чем нас убеждаете?
(38) Так Вы читайте, а не только пишите и станет всё понятно.
Не ленивый, повторю ещё раз.
Почему Вы решили, что запись в индекс происходит долго? Я не вижу никаких оснований, т.к. индекс не что иное как дерево, а дерево это частный случай списка.
Ну и так по мелочи:
Я так и не понял зачем лезть в план запроса.
Во-первых план запроса не является статичным, и для одного и того же запроса меняется в зависимости от ситуации. Я думаю, с этим встречался практически каждый когда один и тот же запрос, в одной и той де базе отрабатывает очень по разному.
Если нужно найти узкое место, зачем лезть в план построения запроса? Можно и без этого получить данные какая часть запроса отрабатывает медленно, и сделать соответствующие выводы.
(39)
Поделитесь, пожалуйста, как можно ДОСТОВЕРНО получить сведения о том какая часть запроса отрабатывает медленно, не заглядывая в план запроса. Эмпирически, основываясь на собственном опыте — да можно. Но эта информация будет носить вероятностный характер. План запроса ДОСТОВЕРНО показывает — какая часть запроса работает медленно здесь и сейчас. Вот и вся причина туда заглядывать.
(42) Сами себе противоречите 🙁
Во-первых план запроса не является статичным, и для одного и того же запроса меняется в зависимости от ситуации. Я думаю, с этим встречался практически каждый когда один и тот же запрос, в одной и той де базе отрабатывает очень по разному.
Если нужно найти узкое место, зачем лезть в план построения запроса? Можно и без этого получить данные какая часть запроса отрабатывает медленно, и сделать соответствующие выводы.
консоль запросов позволяет получить исчерпывающие ответы.
…
вывод плана выполнения запроса, а также SQL-текст запроса, сформированного в СУБД. Для СУБД Microsoft SQL Server план выполнения выводится в виде дерева, а для остальных СУБД – в текстовом формате технологического журнала. Для упрощения анализа запросов также предусмотрено два режима отображения текстов запросов: с именами таблиц и колонок СУБД или с именами объектов метаданных и реквизитов конфигурации (только в обработке для «1С:Предприятие» версии 8.3).
Отличный слог, хорошие статьи. Пишите еще!
Ссылка на вашу «Под капотом управляемых форм» у меня вообще, можно сказать, в буфере обмена. Раздаю направо и налево.
Эта тоже хороша, жалко для меня пользы нет. Ждем продолжения 🙂
(43)
В чём Вы видите противоречие?
Я утверждал, что узкое место можно обнаружить и не заглядывая в план запроса. Разве это не так?
Консоль позволяет вывести план запроса, и? С чего вы решили что раз позволяет, значит это крайне ценная информация?
Несерьезно какая-то у Вас тут атмосфера. Показал Вам инструмент, чтобы Вы колесо не изобретали. Сразу все на меня накинулись: «Да как я могу иметь другую точку зрения». У Вас тут что, секта?
(45)
Не совсем так. Например, в запросе, который вы крутите в консоли запросов, при отборе по высокоселективным данным у Вас может и не быть затыка, если же потом отбор измениться, то селективность другого значения может оказаться иной (низкой) и тот же самый запрос с тем же самым планом запроса, сохраненным в процедурном кеше, выполнится за весьма длительное время.
У меня на практике встречались случаи, когда реально скорость одного и того же запроса могла измениться со временем. Консоль, допустим, покажет, какой конкретно запрос (а подзапрос?) тормозит, но в реальной жизни может оказаться, что этот запрос тормозит только на определенных отборах, а на других работает хорошо. И механизм преодоления таких проблемных ситуаций лежит за пределами консоли запросов — он в профайлере, в планах запросов, в планах обслуживания, в создании нескольких запросов для разных отборов, чтобы планировщик для каждого из них подобрал оптимальный вариант, а не использовал сохраненный в процедурном кеше план.
Неповторимый слог Андрея, повествующих о, казалось бы,замороченных вещах в очень доступной и простой форме.
Ты точно будешь удостоен вторым параллелепипедом!
Отлично написано!
Объяснить сложные вещи простым языком — это дано не каждому.
На фразе «тут мы приближаемся к быстродействию тетеньки из регистратуры»
— ржал минут 10, это просто супер!!
Большой респект автору.
Статью прочитал и понял, что планы запросов как не смотрел никогда, так и не буду, скорей всего, смотреть.
зы Статуэтка от Инфостарта есть.
Спасибо за статью! Написано живо и доходчиво. Ждем продолжения.
годнота
Большое спасибо! Наконец-то нашелся автор, который объяснил наглядно и доходчиво! Даже мне все стало понятно) Очень жду продолжения!
(11) по секрету вам скажу, изучив планы запроса несколько раз, через какое-то время, вы начнете писать запросы, которые будут одинакого быстро работать в разных базах с первого раза! только тссс…
Статья хороша для тех, кто еще не знаком с планами запроса, жалко ее небыло тогда, когда я проходил курсы на эксперта по 1С, потратил бы меньше времени на осознание 🙂
(53) Только недавно пришлось разбираться в плане запросов, так как все остальное себя исчерпало. Но то ли я дурак, то ли лыжа не едут)) Ничем мне не помогла портянка запроса в терминах SQL. Да, я увидел, что совсем криминального там ничего нет, но причины зависания запросов я так и не нашел. В результате максимально выкинул все возможное и ограничив оставшееся через «выразить». Тогда запрос начал работать стабильнее.
В общем, пока остался при своем мнении, что план запроса последняя мера. По крайней мере для меня, в сегодняшних реалиях.
(55)
Ну уж ограничить лишние запросы к составному реквизиту это пожалуй «маст хев» для более менее больших, возможно в будущем больших таблиц, тут даже в план не надо лезть 🙂
А вообще есть в инете много инфы как работать с планом запроса и профайлером, ну и советую курс от Гилева по подготовке к 1с эксперту, сам его проходил, там очень много посвящено работе с планом запроса и как раз много практических примеров.
(48) Блиц из Зверополиса ))
Статья отличная. Давно не читал технических статей написанных таким живым языком.
Спасибо автору.
(37)
Да, мультисет — это не просто список, а упорядоченный список, т.е. упорядоченное хранилище кеу->value с прямым и обратным итератором. Вставка и поиск в мультисете — это log2(N), при этом в неупорядоченный список вставить можно за О(1). А для вставки в деревья SQL-базы необходимо записать страницу, в которую вставили данные или индекс, на диск, а т.к. на диск пишется не просто двадцать, допустим, байт индекса, а кластер целиком, то стоимость операции вставки при множестве индексов равна как минимум времени случайной записи такого количества кластеров, которое равно количеству индексов плюс один — сама таблица с данными. При этом если страницы хранения индекса не хватит, то придется на каждый такой индекс и таблицу записать еще по одному кластеру. И если у нас дисковая подсистема допустим выдает 40к IOPS на операциях записи 4к-блоков, то в лучшем случае вставка у на с в индексированную таблицу ограничится этими IOPS деленными на количество индексов + таблица. Из-за этого БД могут эксплуатировать дисковую систему при множественных непоследовательных вставках достаточно сильно, выдавая этакие 1к TPS при записи (тот же pg_bench).