Индексы(и алгоритм) для сложных соединений с фильтрацией09.02.2024, 12:33. Показов 2024. Ответов 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
|
|||
|
1307 / 361 / 98
Регистрация: 14.10.2022
Сообщений: 1,105
|
||
| 13.02.2024, 11:17 | ||
|
В рассуждениях пропущено понятие "селективность", а именно - насколько разнообразны значения в твоих полях.
Если, например, в каких то полях разнообразие значений не очень велико, типа 0..1, то строить индекс для этих полей особенного смысла не имеет (ну, если только нулей не меньше на пару порядков чем 1. Тогда фильтрованный индекс можно построить, для 0). Потому что при поиске индекс, скорее всего, использован не будет, а будет использовано именно сканирование PK. Можно снести все индексы, кроме очевидных, и заставит пользователей поработать с БД, записав трейс. И потом этот трейс, опять же, скормить дейта тюннинг адвизору. И посмотреть, что он посоветует. Потому что данная задача, эффективно, не решается с помощью того подхода, который ты описал. Не конкретно данного про поля int и т.д., а вообще, концептуально, данного подхода. Это попытка изобрести велосипед. Изобретать велосипеды можно и нужно, но, в данном случае - лучше взять готовый. Объемы мизерные, задача типовая, количество индексов - какие-то два десятка. Фигня в общем. Задача не стоит тех умственных усилий, которые ты на нее тратишь.
0
|
||
| 13.02.2024, 12:43 [ТС] | |||||
![]() Спасибо за варианты. ![]() А список комбинаций далеко не полный. В общем, посмотрим…
0
|
|||||
|
1307 / 361 / 98
Регистрация: 14.10.2022
Сообщений: 1,105
|
|||||||
| 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 | |
|
Алгоритм построения библиотеки классов по описанию сложных объектов. составить алгоритм и программу вычисления значений сложных ф-ций
Одна форма для нескольких менеджеров. Открыть форму с фильтрацией Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
сукцессия 30. Фосфорный и азотный замки по "честному" закону лимитирования Либиха
anaschu 16.07.2026
Основные достижения за последние дни
1. Механизм отложенного высвобождения фосфора
Добавлен специальный пул для медленного разложения меланизированных гиф ЕСМ
Реализована разная скорость. . .
|
Запрет пометки на удаление и отмены проведения
Maks 16.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "ПутевойЛист" разработанного в КА2.
Задача: запретить помечать на удаление и отменять проведения путевого листа при условии, если он сдан. . .
|
Как надо было делать правильно - вообще не слушать ИИ, его дело - текст.
Hrethgir 15.07.2026
А вообще надо было делать не так, чтобы не исправлять ошибку https:/ / www. cyberforum. ru/ blogs/ 223907/ 10996. html , правильно было : удалил кнопку, а потом добавил её.
Всё это стресс конечно. Почему?. . .
|
Знаете, от чего появляется стресс?
kumehtar 15.07.2026
Стресс появляется оттого, что вы, зная как поступить правильно, делаете наоборот.
Ларри Уингет
|
|
Нас бьют, а мы крепчаем? Какая чушь!
kumehtar 15.07.2026
Вот это вот бытующее мнение, что человек меняется только под действием проблем, всегда считал вредоносным. Поверь, от проблем у людей появляются не изменения, а нервное расстройство и ПТСР. А. . .
|
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров
В текущей версии модели успешно реализован ключевой механизм. . .
|
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям
Реализованные компоненты:
Механизм закисления почвы через протонную помпу
Конкуренция между типами микориз
pH как триггер сукцессии
C/ P соотношение. . .
|
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
|