powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Помогите с оптимизацией запроса
8 сообщений из 8, страница 1 из 1
Помогите с оптимизацией запроса
    #39708125
alx71
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
create table t1
(
id number(12) primary key t1_pk
)
;

create table t2
(
id number(12) foreign key t2_fk references t1(id)
)
;
create index t2_id_i on t2(id);



Необходимо для каждой записи из t1 выбрать не более 10 записей из t2 по условию t1.id=t2.id

Код: plsql
1.
2.
3.
4.
5.
select * from
(
  select t1.id,t2.id,row_number() over (partition by t1.id order by t1.id) rn from t1,t2 where t1.id=t2.id
) where rn <= 10
;



Проблема в том, что такой запрос приводит к index full scan по t2. FIRST_ROWS не помогает.

Можно ли оптимизировать?
...
Рейтинг: 0 / 0
Помогите с оптимизацией запроса
    #39708134
Фотография Щукина Анна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alx71,

Ваша хотелка хорошо бы легла на механизмы [[CROSS | OUTER] APPLY | LATERAL] джойнов в паре с TOP-N запросами (OFFSET FETCH N FIRST | LAST ROWS ONLY).
Но такое официально доступно лишь с версии 12с.

З.Ы.
Небольшими хитростями можно заставить работать LATER на версии 11g. Логику топ-n запросов придется городить по старинке - через ROWNUM
...
Рейтинг: 0 / 0
Помогите с оптимизацией запроса
    #39708167
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Щукина Анна,

можете привести пример с TOP-N для случая partition by t1.id в 12-ке

.....
stax
...
Рейтинг: 0 / 0
Помогите с оптимизацией запроса
    #39708170
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alx71Необходимо для каждой записи из t1 выбрать не более 10 записей из t2 по условию t1.id=t2.id

Код: plsql
1.
2.
3.
4.
5.
select * from
(
  select t1.id,t2.id,row_number() over (partition by t1.id order by t1.id) rn from t1,t2 where t1.id=t2.id
) where rn <= 10
;

Код: plsql
1.
2.
3.
4.
select * from
(
  select t2.id,t2.id,row_number() over (partition by t2.id order by t2.id) rn from t2
) where rn <= 10;
...
Рейтинг: 0 / 0
Помогите с оптимизацией запроса
    #39708190
alx71
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
-2-, я упростил свою ситуацию. IRL t1 выбрасывать нельзя.
...
Рейтинг: 0 / 0
Помогите с оптимизацией запроса
    #39708231
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alx71я упростил свою ситуацию.А я упростил свою оптимизацию.
...
Рейтинг: 0 / 0
Помогите с оптимизацией запроса
    #39708234
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alx71,

Селект ОЧЕНЬ упрощен, и я не уверен что он в ТАКОМ виде тоже работает по full scan.

А так, попробуйте хинтами прибить
https://docs.oracle.com/cd/B12037_01/server.101/b10752/hintsref.htm
или покажите оригинальный селект
...
Рейтинг: 0 / 0
Помогите с оптимизацией запроса
    #39708758
Фотография Щукина Анна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
StaxЩукина Анна,

можете привести пример с TOP-N для случая partition by t1.id в 12-ке

.....
stax
Oracle 12c под рукой нет, покажу на скульсервере.
Тестовые данные - немного отличается по синтаксису от оракла,
но основная часть запроса, в том числе OUTER APPLY подзапрос (?) и OFFSET / FETCH - в точности соответствуют оракловым, ибо - стандарт ANSI ;)

запрос, проверка на скульфидле: http://sqlfiddle.com/#!18/9eecb/34913
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
-- Тестовые данные:
with
-- Первая таблица, на три строчки:
t1 (id) as 
    (
      select * from (values
                       (1)
                      ,(2)
                      ,(3)
                    ) v(id)
    )
-- Вторая таблица, для каждой записи из t1 в ней есть по 5 записей с разными значениями f
,t2 (id_t1, f) as
    (
      select * from (values
                       (1,1)
                      ,(1,2)
                      ,(1,3)
                      ,(1,4)
                      ,(1,5)
                      ,(2,1)
                      ,(2,2)
                      ,(2,3)
                      ,(2,4)
                      ,(2,5)
                      ,(3,1)
                      ,(3,2)
                      ,(3,3)
                      ,(3,4)
                      ,(3,5)
                    )v(id_t1, f))
-- Основной запрос:
select t1.id, cav.f 
  from t1
 cross apply -- Доступно с версии Oracle 12c
   (
     select f 
       from t2
      where t2.id_t1 = t1.id
-- Для каждой записи из t1 выбираем по три первых строки, в сортировке по f:
-- (по сути - аналог row_number() over(partition by t1.id order by t2.f) <= 3)
     order by t2.f
     offset 0 rows            -- Доступно с версии Oracle 12c
      fetch next 3 rows only  -- Доступно с версии Oracle 12c
   ) cav

...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Помогите с оптимизацией запроса
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]