Индексы(и алгоритм) для сложных соединений с фильтрацией09.02.2024, 12:33. Показов 2082. Ответов 26
Приветствую!
Продолжаю разбираться с правилами построения индексов… Есть таблица смет С и ресурсов к ним Р (в одной смете один и более ресурсов). Связаны по ключу сметы Ск. Таблицу смет нужно отфильтровать по некоторым полям, в том числе, соединяя с другими таблицами. Таблицу ресурсов нужно также отфильтровать по некоторым полям, в том числе, соединяя с другими таблицами, включая Р(Ск) — то есть, учесть фильтр по сметам. Проблема №1 состоит в том, что, если делать всё "в лоб", то получается каша — сметы-то соединяются с другими таблицами по одному ключу, а вот ресурсы используют Рк ключ ресурса — для связи с другими таблицами, и то Р(Ск) ключ сметы — для связи со сметой. К тому же, ещё нужен такой индекс, который бы и фильтры учёл для обоих таблиц. Я не могу понять, как правильно в таком случае "разрулить" логику. Что делать сначала, что потом, какие индексы строить — для достижения максимальной скорости. Проблема №2 в том, что фильтры(переменные) для обоих смет могут переданы все, часть или ни одного. То есть, как будто, для каждой комбинации фильтров нужно построить некластерный индекс. Даже, отсеивая те комбинации, когда используются только первые (а не все) ключи индекса (он подходит), всё - равно получается очень много и это ерунда. Я придумал имитировать фильтр, если он не передан, то есть использовать минимальное количество некластерных индексов, "фильтруя" ключи в них типа Where Field > 0 (для Int полей), чтобы можно было использовать ключи индекса без разрывов. Вроде, это нормально получается. Интересно ваше мнение. По каждой таблице я могу построить кластерный индекс под эту задачу. Время построения индексов на этих и связанных с ними таблицах, не учитывается во времени работы. Делается один раз. Сейчас делаю через временные таблицы(для смет и ресурсов), но на них время построения индексов уже включается во время работы и портит его. Например, при простом запросе (отфильтровать каждую таблицу по одному разному полю и соединить между собой) я вижу, что сначала используются индексы для отбора каждой из таблиц (без поля соединения между таблицами) и потом таблицы джойнятся между собой.
0
|
|
| 09.02.2024, 12:33 | |
|
Ответы с готовыми решениями:
26
Алгоритм вычисления сложных выражений
Алгоритм построения библиотеки классов по описанию сложных объектов. |
| 13.02.2024, 10:15 [ТС] | |||
|
Какие индексы я должен построить на это всё добро? Если я делаю индекс (для упрощения считаем все поля Int от 1 без Null) f1, f2, f3, f4 … f10, то он будет неэффективен для ВСЕХ фильтров без f1. Ок, Можно подменить фильтр по f1 условием f1 > 0. И тогда будет один бесполезный, но не очень долгий прогон, зато прочие фильтры хорошо отработают. Можно также подменять и другие фильтры, когда их нет. Но, если фильтров 2-3 и это поля в хвосте индекса, то пользы от него уже не будет, а только вред и в сравнении с индексом чётко под поля фильтра скорость будет земля и небо. Наверное, вообще без индекса будет быстрее в этом случае, но, т.к. псевдофильтры стоят, то индекс подхватится и будет делать бесполезную работу. Ок, пусть будет индекс под каждое из основных полей, но 1ым в нём будет идти Primary Key таблицы, вторым — уже само очередное поле, в Include ничего не пишем, т.к. возвращаться будет только Primary Key, и в Where индекса также не пишем ничего. Это позволит ступенчато отфильтровывать таблицу, где каждый прогон со 2го фильтрует сначала по отобранным ранее Primary Key и потом уже по самому полю. Порядок отбора (выбор очерёдности полей) должен быть таким, чтобы оставалось минимальное количество ключей. Например, я знаю что, если передан фильтр по сметам (их 20 000), то первым я буду применять его, а фильтр по типу ресурса (всего их 4) я буду применять в конце (или перед фильтром по булевым полям, если такие фильтры есть). Можно сказать, что нужно выбирать более селективные поля, но, могут быть исключения. 1ый прогон фильтрует только по полю (без Primary Key). [примерно] Этот вариант я вчера и имел в виду, но он тоже не самый удобный, как мне кажется. Да — он универсальный. Количество индексов в таблице примерно можно представить и их будет немного (намного меньше, чем индексов комбинаций полей). Добавим индекс(-ы) для группировки и всё. Да, проговорю в который раз, это будет медленнее, чем индекс "под задачу", но, при правильном использовании очерёдности применения фильтров, должно быть достаточно быстро. Пока я склоняюсь к чему-то среднему: иметь 3-5 индексов с 3-4мя полями + Primary Key. Один из таких индексов будет опорным — в нём будут расположены самые селективные поля из часто встречающихся. Остальные индексы помогут дофильтровать то, что осталось после первого. P.S.: принудительно индекс навязать умею, но не применяю (только для тестов), актуальный план запроса анализирую, рекомендации плана принимаю к сведению (не бездумно).
0
|
|||
|
1310 / 363 / 99
Регистрация: 14.10.2022
Сообщений: 1,107
|
||
| 13.02.2024, 11:17 | ||
|
В рассуждениях пропущено понятие "селективность", а именно - насколько разнообразны значения в твоих полях.
Если, например, в каких то полях разнообразие значений не очень велико, типа 0..1, то строить индекс для этих полей особенного смысла не имеет (ну, если только нулей не меньше на пару порядков чем 1. Тогда фильтрованный индекс можно построить, для 0). Потому что при поиске индекс, скорее всего, использован не будет, а будет использовано именно сканирование PK. Можно снести все индексы, кроме очевидных, и заставит пользователей поработать с БД, записав трейс. И потом этот трейс, опять же, скормить дейта тюннинг адвизору. И посмотреть, что он посоветует. Потому что данная задача, эффективно, не решается с помощью того подхода, который ты описал. Не конкретно данного про поля int и т.д., а вообще, концептуально, данного подхода. Это попытка изобрести велосипед. Изобретать велосипеды можно и нужно, но, в данном случае - лучше взять готовый. Объемы мизерные, задача типовая, количество индексов - какие-то два десятка. Фигня в общем. Задача не стоит тех умственных усилий, которые ты на нее тратишь.
0
|
||
| 13.02.2024, 12:43 [ТС] | |||||
![]() Спасибо за варианты. ![]() А список комбинаций далеко не полный. В общем, посмотрим…
0
|
|||||
|
1310 / 363 / 99
Регистрация: 14.10.2022
Сообщений: 1,107
|
|||||||
| 13.02.2024, 12:51 | |||||||
|
Некоторые, возможно, необходимо удалить.
1
|
|||||||
| 13.02.2024, 13:09 [ТС] | |
|
uaggster, спасибо. Да — есть уже у нас запрос для анализа и даже отдельный человек для этого (не я). Но, пока индексы находятся в постоянном изменении, толку от такого анализа мало. Самые очевидные "якори" уже удалили.
0
|
|
|
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
|
||||||
| 13.02.2024, 18:55 | ||||||
|
Ошибка начинающих - наплодить гору индексов, в надежде, что они станут использоваться при соединении таблиц и все запросы чудесным образом залетают.
Потом приходит разочарование - не залетало. Пример для размышления - а почему не залетало
1
|
||||||
| 14.02.2024, 09:29 [ТС] | ||
|
invm, спасибо! Хороший пример!
Подобные указания [пока] не использую. План запроса показывает, что пользователь сошёл с ума ![]() Единственное, что могу сказать по этому поводу это то, что при соединении таблиц, в которой один индекс по PK(Clust), а в другой по NonClust — это то, что для Merge нужно будет выполнить сортировку (из-за Clust) и нередко видел, что это по времени дольше, чем соединять по 2ум NonClust.
0
|
||
| 14.02.2024, 09:29 | |
|
Алгоритм построения библиотеки классов по описанию сложных объектов. составить алгоритм и программу вычисления значений сложных ф-ций
Одна форма для нескольких менеджеров. Открыть форму с фильтрацией Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала.
Ниже прикреплён. . .
|
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F
Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU.
Опрашиваются регистры. . .
|
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка:
Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
|
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо
Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
|
|
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман.
Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
|
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
|
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
|
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ
Основная суть и тезисы по измерениям:
0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема.
Объект не может перемещаться в 0D.
1D (Первое измерение):. . .
|