[closed]
а индексы обозначать пушкен будет? Ну и where тоже
ну ты первым запросом всегда фактически фуллскан заставляешь делать - ищешь же максимум по всем партициям фактически
если для любого b выдача будет заведомо непустая, то можно пойти на изменение логики: сделать индекс по b, искать по нему и лишь затем применять оконную функцию, но если есть случаи, когда для b может быть ничего не найдено в первом запросе, то результат у исходного запроса и у переписанного будет отличаться
короче, без изменения логики быстро первую запись не получить, ну а без знания того, какие данные хранятся и как они вносятся - логику не переписать без ущерба
если для любого b выдача будет заведомо непустая, то можно пойти на изменение логики: сделать индекс по b, искать по нему и лишь затем применять оконную функцию, но если есть случаи, когда для b может быть ничего не найдено в первом запросе, то результат у исходного запроса и у переписанного будет отличаться
короче, без изменения логики быстро первую запись не получить, ну а без знания того, какие данные хранятся и как они вносятся - логику не переписать без ущерба
хотя можно сделать вот как:
1. индекс по b
2. индекс по полям в partition by
3. добавляем в запрос условие not exist'ом, что для найденного b в указанных условиях партиции нет члена большего, чем b.
4. ограничиваем по rownum (или делаем top 1)
5. возможно придётся принудительно указать хинт, чтобы джойн шёл не хешом, а через nested loops
тогда получится то же самое в любом случае
p.s. в этом случае понадобится формально два прохода таблицы, но так как по индексам, то пох
1. индекс по b
2. индекс по полям в partition by
3. добавляем в запрос условие not exist'ом, что для найденного b в указанных условиях партиции нет члена большего, чем b.
4. ограничиваем по rownum (или делаем top 1)
5. возможно придётся принудительно указать хинт, чтобы джойн шёл не хешом, а через nested loops
тогда получится то же самое в любом случае
p.s. в этом случае понадобится формально два прохода таблицы, но так как по индексам, то пох
1 2 все индексы есть
3 не совсем понял о чём ты, но уже не актуально - переделали запрос на без окна
4 там и так /*+ FIRST_ROWS */ стоит
5 хз что с этим запросом надо сделать, чтобы там хэшджойн был.
И вопрос был совсеееем не по оптимизации, если ты заметишь. В общем как обычно на фл, заходим в тему, придумываем сами себе вопрос и отвечаем на него, не важно, что было в начале топика.
3 не совсем понял о чём ты, но уже не актуально - переделали запрос на без окна
4 там и так /*+ FIRST_ROWS */ стоит
5 хз что с этим запросом надо сделать, чтобы там хэшджойн был.
И вопрос был совсеееем не по оптимизации, если ты заметишь. В общем как обычно на фл, заходим в тему, придумываем сами себе вопрос и отвечаем на него, не важно, что было в начале топика.
жаль, что ты нихуя не понял, но рад, что всё получилось
4 там и так /*+ FIRST_ROWS */ стоитэто хинт, но в данном случае от него мало пользы...
У меня на работе запросов, требующих получения записей по максимуму/минимуму значения море (правда, в большинстве случаев, такое значение одно) и почти всегда используется форма
select ...
from tbl t
where .....
and tbl.field1 = (select max(field1) from tbl where ....)
Иногда в критичных к быстродействию местах (либо при большом объеме данных) приходится идти на небольшую денормализацию данных (сохраняем маркеры последних записей, либо копируем поле в основную таблицу).
Ну на самом деле та конструкция, которую ты привёл в общем случае будет медленнее аналитической функции за счёт двух проходов таблицы. При наличии покрывающего индекса, у которого вставлено desc по полю с максимумом - быстрее будет, да, но так можно и аналитическую подогнать, а использований таблицы/индекса в случае аналитической будет меньше.
Ну а что кротишка first_rows приводит - так это от незнания того факта, что у оракла есть только два подхода: rule и all_rows, а хинты choose и first_rows просто заставляют выбирать наиболее подходящий режим.
Ну а что кротишка first_rows приводит - так это от незнания того факта, что у оракла есть только два подхода: rule и all_rows, а хинты choose и first_rows просто заставляют выбирать наиболее подходящий режим.
у оракла есть только два подхода: rule и all_rows, а хинты choose и first_rows просто заставляют выбирать наиболее подходящий режим.Что-то ты странное говоришь.
ALL_ROWS
The optimizer uses a cost-based approach for all SQL statements in the session regardless of the presence of statistics and optimizes with a goal of best throughput (minimum resource use to complete the entire statement). This is the default value.
FIRST_ROWS_n
The optimizer uses a cost-based approach, regardless of the presence of statistics, and optimizes with a goal of best response time to return the first n number of rows, where n equals 1, 10, 100, or 1000.
FIRST_ROWS
The optimizer uses a mix of cost and heuristics to find a best plan for fast delivery of the first few rows.
Note that using heuristics sometimes leads the optimizer to generate a plan with a cost that is significantly larger than the cost of a plan without applying the heuristic. FIRST_ROWS is available for backward compatibility and plan stability; use FIRST_ROWS_n instead.
WHERE усл1 and усл2 and усл3у тебя тут только условия соединения, или же есть какие-либо условия ограничения на отдельные таблицы, типа where a.сиськи = 3 или там a.prodate > 8.03.2012?
Я могу ошибаться в деталях, но суть в том, что хинты - это не отдельные режимы работы оптимизатора. Можно либо применять cost-based подход, либо использовать rule-based подход, либо комбинировать их. В данной конкретной задаче предельно ясно как придётся работать с партициями, и на каких множествах осуществлять поиск, чтобы это заняло наименьшее время. Вся задача - это заставить оптимизатор отработать по той схеме, которую для него придумаешь.
На этой фразе, кстати, я обнаружил недостаток собственных знаний:
The DYNAMIC_SAMPLING hint lets you control dynamic sampling to improve server performance by determining more accurate predicate selectivity and statistics for tables and indexes. You can set the value of DYNAMIC_SAMPLING to a value from 0 to 10. The higher the level, the more effort the compiler puts into dynamic sampling and the more broadly it is applied. Sampling defaults to cursor level unless you specify a table.
но так как в описании этого явно не указано, то хз.
На этой фразе, кстати, я обнаружил недостаток собственных знаний:
cost-based approach, regardless of the presence of statisticsв моём представлении такое возможно при использовании разве что DYNAMIC_SAMPLING:
The DYNAMIC_SAMPLING hint lets you control dynamic sampling to improve server performance by determining more accurate predicate selectivity and statistics for tables and indexes. You can set the value of DYNAMIC_SAMPLING to a value from 0 to 10. The higher the level, the more effort the compiler puts into dynamic sampling and the more broadly it is applied. Sampling defaults to cursor level unless you specify a table.
но так как в описании этого явно не указано, то хз.
Оставить комментарий
kill-still
Есть такой запрос:Первый рекорд он одаёт через 1.5 минуты. и дальше ноностопом очень быстро их выплёвывает.
Такой же запрос отдаёт первый отклик очень быстро (что в принципе логично):
Есть необходимость ускорить выдачу первого отклика.
Общее время выполнения запроса в результате преобразования может вырасти в пределах разумного.