|
|
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
Друзья, всех с прекрасным зимним выходным! Небольшой соцопрос коллективного разума на тему оптимизации. То ли я недостаточно хорошо думаю, то ли действительно нет универсального рецепта... Однако, мыслей - хаотичный рой, никак не упорядочу. Дано: есть некая основная таблица (схема "факты - измерения" ту неприменима) и несколько с ней связанных. Некоторые - справочники, некоторые - довольно динамично обновляются. Есть отношения как один ко многим, там и многие к одному от основной к связанным. Ни в одной из связанных наличие соответствий не обязательно. И есть 3 десятка параметров, по которым нужно осуществлять выборку из всего этого безобразия, причем могут быть указаны как все 30, так и ни одного. В табличках - по 2-4 млн записей, и это уже вызывает проблемы производительности. Как в мире принято такое реализовывать? Честно гуглил - рецептов не нашёл (может плохо искал, хоть и долго) Пусть технология такова, например: передать 30 параметров в функцию, вернуть курсор приложению. Просто запрос с параметрами пробовал. Не удалось заставить строить корректные планы при разных наборах параметров, как не хинтуй. Пробовал матвью строить и индексировать - оказалось глупой идеей, слишком динамично изменяются некоторые данные. Пробовал в денормализованную таблицу данные сливать, индексировать, и искать по ней - не сильно помогло. Блокировок много (приходится UL ставить) и таблица большая - выхлоп с блока маленький, чтений много, индексов много - запись медленная. Динамический SQL в зависимости от набора параметров - пробовал, даже хинты в динамике вставлял, но приходится использовать литералы, т.к. не придумал, как забиндить произвольный набор из 30. Писать if/case с тысячами ветвлений - кмк так себе идея... В итоге сейчас работает на денормализованной таблице + динамика с литералами. Так работало быстрее остальных вариантов. Но начали одолевать блокировки - увеличивается интенсивность изменений. Да и планы строятся так себе... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2017, 13:37 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
1) Выявить набор наиболее часто передаваемых параметров и подумать в сторону партиционирования по ним исходного набора данных. 2) gandalf-the-greyно приходится использовать литералы, т.к. не придумал, как забиндить произвольный набор из 30Тут я тебя не понял. Литералы и ограничение на 30 - вещи несвязанные. 3) gandalf-the-greyВ итоге сейчас работает на денормализованной таблице + динамика с литералами. Так работало быстрее остальных вариантов. Но начали одолевать блокировки - увеличивается интенсивность изменений.О каких блокировках идет речь? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2017, 14:33 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
AmKad1) Выявить набор наиболее часто передаваемых параметров и подумать в сторону партиционирования по ним исходного набора данных. Да, спасибо, думал об этом. Однако смущает судьба запросов, набор параметров в которых не будет "часто передаваемым". Есть прогноз, что таких будет много. AmKad2) gandalf-the-greyно приходится использовать литералы, т.к. не придумал, как забиндить произвольный набор из 30Тут я тебя не понял. Литералы и ограничение на 30 - вещи несвязанные. Да, криво объяснил. Попробуем так: если зафигачить в запрос ВСЕ предикаты (30 штук) в виде: Код: plsql 1. то в плане сплошные full scan, даже если один из параметров на PK одной из таблиц ссылается (видимо, из-за left join'ов) Если же формировать динамику, в зависимости от переданных параметров, то для написания потом execute immediate для формирования using придётся обернуть ещё в одну динамику. AmKad3) gandalf-the-greyВ итоге сейчас работает на денормализованной таблице + динамика с литералами. Так работало быстрее остальных вариантов. Но начали одолевать блокировки - увеличивается интенсивность изменений.О каких блокировках идет речь? Данные обновляются из нескольких источников, по логике приложения надо лочить таблицу при этом, иначе сплошные дедлоки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2017, 14:56 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
gandalf-the-greyЕсть отношения как один ко многим, там и многие к одному от основной к связанным. Прошу прощения! Поторопился, от основной к связанным отношение многие/1 к 1! Никаких один ко многим нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2017, 15:25 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
gandalf-the-grey Код: plsql 1. то в плане сплошные full scan, даже если один из параметров на PK одной из таблиц ссылается (видимо, из-за left join'ов) Если же формировать динамику, в зависимости от переданных параметров, то для написания потом execute immediate для формирования using придётся обернуть ещё в одну динамику .Используй dbms_sql. В частности для биндинга - dbms_sql.bind_variable. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2017, 15:58 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
gandalf-the-greyДинамический SQL в зависимости от набора параметров - пробовал, даже хинты в динамике вставлял, но приходится использовать литералы, т.к. не придумал, как забиндить произвольный набор из 30. Quiz on Method 4 Dynamic SQL: Variable Number of Placeholders ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2017, 16:38 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
Elic, спасибо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2017, 17:25 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
>gandalf-the-grey, сегодня, 13:37 http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1247887&msg=20158426] [20158426] >...Дано: есть некая основная таблица ... А если так (мне удалось серьезно увеличить скорострельность): 1. Обработку параметров переносим в пакет, используя PL/SQL, 2. Как результат обработки строим необходимое количество промежуточных динамических запросов, 3. Динамически строим основной запрос, 4. Последовательно выполняем промежуточные запросы с хранением выборок во временных таблицах (использую и курсоры), 5. Выполняем основной запрос, 6. Передаем выборку клиенту, 7. Подчищаем за собой. С уважением, Владимир. з.ы. нужно терпение и крепкие нервы при отладке. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2017, 17:41 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
ВМоисеев7. Подчищаем за собой.Быдло-mssql-подход, требующийВМоисеевтерпение и крепкие нервы при отладке. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2017, 17:53 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
ВМоисеев, Да, такой вариант прорабатывался. Но не исключены ситуации, когда фильтры по связанным таблицам низкоселективны или вообще отсутствуют - надо лезть в статистику каждый раз и самому определять, "стоит ли овчинка выборки" во времянку. В худшем случае все времянки могут оказаться просто копиями исходных таблиц и повлекут лишь деградацию... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2017, 18:46 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
Elic, ещё несколько вопросов, если не затруднит. Ваши ответы всегда весьма полезны. 1) Как думаете, почему в статье рекомендован 7-й вариант с execute immediate? Мне более импонирует 4-й. Хотя бы тем, что через DBMS_SQL.BIND_VARIABLE явно передаются параметры разных типов, исключая неявные или закостыленные в запрос преобразования. У меня, к примеру, жизнь осложняется тем, что некоторые из параметров - массивы. DBMS_SQL.BIND_ARRAY? 2) Этот вопрос не особо связан с темой, но в моём случае напрямую. Имеем веб-приложение + пул соединений --> каждый запрос с веба приходит в произвольную сессию из пула. Используем механизм прикладных псевдосессий. Результаты поиска юзеру на гуй надо отдавать постранично, а не всю портянку (которая может тупо в ОЗУ не влезть к нему). Имеет смысл сохранять, например, в nologging-таблицу по результатам поиска набор ROWID от ведущей таблицы, чтобы при перемещении юзера по страницам отдавать нужные порции, не выполняя основного тяжелого запроса; или это все от лукавого и стоит переложить нагрузку на средний слой, обязав его доставать всю портянку и рулить постраничным разбиением самостоятельно? В первом варианте весь груз ложится на БД - хранить временные списки ROWID от запросов пары тысяч юзеров, хоть и неподолгу, но, в худшем случае, до миллиона записей каждый Во-втором варианте появляется много ненужного трафика от БД к среднему слою За ресурсы среднего слоя особо не беспокоимся, там масштабируемый кластер, а вот БД в одном экземпляре... Как сейчас принято такие задачи решать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2017, 19:29 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
gandalf-the-greyКак думаете, почему в статье рекомендован 7-й вариант с execute immediate?Это не статья. И я не думаю, а вроде как недвусмысленно написал, почему. - Сопровождаемость. gandalf-the-greyМне более импонирует 4-й.Кто не понимает процедурного подхода или не может к нему привести, пишет тонны copy-paste-ного говнокода и вынужден иметь "терпение и крепкие нервы при отладке". gandalf-the-greyХотя бы тем, что через DBMS_SQL.BIND_VARIABLE явно передаются параметры разных типов, исключая неявные или закостыленные в запрос преобразования.Двойное неявное преобразование число-строка-числа безопасно и ради удобства в простейших случаях им можно пренебречь. А вообще, типизация там оставлена в качестве домашнего задания для пытливых умов. gandalf-the-greyжизнь осложняется тем, что некоторые из параметров - массивы . DBMS_SQL.BIND_ARRAY?Поподробней и с примером. gandalf-the-greyпереложить нагрузку на средний слой, обязав его доставать всю портянку и рулить постраничным разбиением самостоятельно?IMHO, путь в никуда. gandalf-the-greyЗа ресурсы среднего слоя особо не беспокоимся, там масштабируемый кластер, а вот БД в одном экземпляре...Странная расстановка приоритетов. Использование БД как транзакционного файлового сервера? gandalf-the-greyКак сейчас принято такие задачи решать?Пока что слишком непарнокопытно-безвоздушно-шарообразно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2017, 20:05 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
Elicgandalf-the-greyКак думаете, почему в статье рекомендован 7-й вариант с execute immediate?Это не статья. И я не думаю, а вроде как недвусмысленно написал, почему. - Сопровождаемость. Спасибо, сразу не дошло. Elicgandalf-the-greyМне более импонирует 4-й.Кто не понимает процедурного подхода или не может к нему привести, пишет тонны copy-paste-ного говнокода и вынужден иметь "терпение и крепкие нервы при отладке". Ну, я готов написать по 2 строки кода на каждый параметр вместо одной, ибо их конечно число. Мне казалось, что DBMS_SQL безопаснее с точки зрения инъекций Elicgandalf-the-greyХотя бы тем, что через DBMS_SQL.BIND_VARIABLE явно передаются параметры разных типов, исключая неявные или закостыленные в запрос преобразования.Двойное неявное преобразование число-строка-числа безопасно и ради удобства в простейших случаях им можно пренебречь. А вообще, типизация там оставлена в качестве домашнего задания для пытливых умов. Согласен. Но есть ещё даты ;) Elicgandalf-the-greyжизнь осложняется тем, что некоторые из параметров - массивы . DBMS_SQL.BIND_ARRAY?Поподробней и с примером. Например, глобально объявлено что-то вроде Код: plsql 1. один из параметров процедуры имеет объявлен как Код: plsql 1. и в случае статического SQL его применение к запросу выглядит как Код: plsql 1. Elicgandalf-the-greyпереложить нагрузку на средний слой, обязав его доставать всю портянку и рулить постраничным разбиением самостоятельно?IMHO, путь в никуда.Возможно. Я лишь знаю, что подобные реализации существуют, на практике не доводилось применить и сравнить. Elicgandalf-the-greyЗа ресурсы среднего слоя особо не беспокоимся, там масштабируемый кластер, а вот БД в одном экземпляре...Странная расстановка приоритетов. Использование БД как транзакционного файлового сервера? gandalf-the-greyКак сейчас принято такие задачи решать?Пока что слишком непарнокопытно-безвоздушно-шарообразно. Создал отдельную тему-вопрос, попытался объясниться понятнее http://www.sql.ru/forum/1247913/tyazhelyy-zapros-i-vydacha-rezultata-polzovatelu-postranichno Про БД как ФС - сорри, тоже не уловил. Архитектуру придумали до разработки и пока работаем с тем, что имеем. Есть кластер WebSphere, бэкенд на жаве, фронт на JS, и один единственный "мозг" на Oracle 11g БД получает данные из нескольких источников, агрегирует, преобразует. Это не OLTP, не DWH... Скорее что-то типа DSS. Но данные некоторые обновляются динамично, кэшировать не получится. Юзер хочет среди этих данных искать, цели и мотивы - разные. В общем случае он может ввести фильтры, по которым отберутся 99% записей. Надо обеспечить комфортную навигацию, учитывая вводные по архитектуре. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2017, 20:42 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
gandalf-the-greyНу, я готов написать по 2 строки кода на каждый параметр вместо одной, ибо их конечно число.Я вижу гораздо более другой коэффициент. gandalf-the-greyМне казалось, что DBMS_SQL безопаснее с точки зрения инъекцийЗначит ты не понимаешь, что такое инъекции. gandalf-the-grey Код: plsql 1. Наверное, коллекция коллекций вполне пролезет. И RTFM member of (в зависимости от мощности). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2017, 21:06 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
>gandalf-the-grey, сегодня, 18:46 http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1247887&msg=20159010][20159010] >Да, такой вариант прорабатывался. Это в определенном смысле абсолютный вариант. Хочешь - строй только один динамический запрос, есть смысл - динамически строй промежуточные запросы. Таким способом мне удалось поднять скорострельность более чем вдвое. Столкнулся с таким моментом - если . . . FROM . . . (SELECT ... FROM ... WHERE) xs1, . . . то (SELECT ... FROM xs1 ...) не могу использовать ни в FROM ни в WHERE. Построив промежуточную выборку в во временную таблицу, получил необходимый результат. С уважением, Владимир ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2017, 21:07 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
gandalf-the-greyбэкенд на жавеПохоже, это и есть gandalf-the-greyБД как ФС ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2017, 21:08 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
ВМоисеев(SELECT ... FROM ... WHERE) xs1, . . . то (SELECT ... FROM xs1 ...) не могу использовать ни в FROM ни в WHERE.RTFM subquery factoring ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2017, 21:12 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
>Elic, сегодня, 21:12 [20159357] Спасибо. С уважением, Владимир ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2017, 21:23 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
>Elic, сегодня, 21:12 http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1247887&msg=20159357][20159357] Обидно. С уважением, Владимир. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.01.2017, 22:20 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
ВМоисеев>Elic, сегодня, 21:12 http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1247887&msg=20159357][20159357] Обидно. С уважением, Владимир. Оберни все это в вышестоящий select. p.s. "cur_viborka" - отличное название для курсора, очень говорящее. Как будто у тебя там может быть cur_update... Самое интересное начнет происходить с названиями, когда будут появляться второй и третий подобный курсоры в одном блоке ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2017, 01:47 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
>Вадиман, сегодня, 01:47 http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1247887&msg=20159803][20159803] >Оберни все это в вышестоящий select. Покажи как: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. С уважением, Владимир. з.ы. ...очень говорящее... На стороне клиента запрашиваю выборку. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2017, 02:38 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
open cur_viborka for SELECT ... FROM ( WITH x as ( SELECT ... ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2017, 03:39 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
>Вадиман, сегодня, 03:39 [20159822] Не проходит. С уважением, Владимир ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2017, 10:52 |
|
||
|
Запрос с множеством параметров к набору таблиц
|
|||
|---|---|---|---|
|
#18+
ВМоисеевНе проходит.Нам твои археологические проблемы неинтересны. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.01.2017, 10:55 |
|
||
|
|

start [/forum/topic.php?fid=52&msg=39393993&tid=1886553]: |
0ms |
get settings: |
7ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
159ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
61ms |
get tp. blocked users: |
1ms |
| others: | 210ms |
| total: | 469ms |

| 0 / 0 |
