powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / двойной select
20 сообщений из 20, страница 1 из 1
двойной select
    #39744114
petrovichvanya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
2.
3.
4.
5.
6.
select * from(
select * from brsactions a
where a.contractid = '3280915'
and a.actioncodeid in (17025310, 17025339, 17050320)
order by a.operdate desc )
where rownum = 1



Здравствуйте, есть возможность вывести так же записи, только без использования второго select ?
...
Рейтинг: 0 / 0
двойной select
    #39744125
viking_dooh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
petrovichvanya,

Для 12с:
Код: plsql
1.
2.
3.
4.
5.
select * from brsactions a
where a.contractid = '3280915'
and a.actioncodeid in (17025310, 17025339, 17050320)
order by a.operdate desc
fetch first row only
...
Рейтинг: 0 / 0
двойной select
    #39744164
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrovichvanyaЗдравствуйте, есть возможность вывести так же записи, только без использования второго select ?

Для семерки
если есть индекс по operdate и operdate is not null

Код: plsql
1.
2.
3.
4.
select /*+ index_desc(a i$brsactions$operdate) */ * from brsactions a
where a.contractid = '3280915'
and a.actioncodeid in (17025310, 17025339, 17050320)
where rownum = 1



.....
stax
...
Рейтинг: 0 / 0
двойной select
    #39744171
petrovichvanya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
оба варианта не подошли, жаль(
...
Рейтинг: 0 / 0
двойной select
    #39744193
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
viking_dooh
Код: plsql
1.
2.
3.
4.
5.
select * from brsactions a
where a.contractid = '3280915'
and a.actioncodeid in (17025310, 17025339, 17050320)
order by a.operdate desc
fetch first row only

Это без первого select, нужно без второго.
...
Рейтинг: 0 / 0
двойной select
    #39744217
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrovichvanya,

CONTRACTID уникальное

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
  1  with t as(
  2  select 1 contractid ,300 actioncodeid, date '2018-11-01' operdate from dual union all
  3  select 2 contractid ,202 actioncodeid, date '2018-11-11' operdate from dual union all
  4  select 3 contractid ,203 actioncodeid, date '2018-11-11' operdate from dual union all
  5  select 4 contractid ,200 actioncodeid, date '2018-11-11' operdate from dual union all
  6  select 5 contractid ,111 actioncodeid, date '2018-11-10' operdate from dual
  7  )
  8  select
  9   max(contractid) KEEP (DENSE_RANK FIRST ORDER BY operdate desc,contractid) contractid
 10  ,max(a.actioncodeid) KEEP (DENSE_RANK FIRST ORDER BY operdate desc,contractid) actioncodeid
 11  ,max(a.operdate) oper_date
 12* from t a
SQL> /

CONTRACTID ACTIONCODEID OPER_DAT
---------- ------------ --------
         2          202 11.11.18
...
Рейтинг: 0 / 0
двойной select
    #39744339
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
viking_doohДля 12с:
fetch first row only


Из серии о сусликах:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
SQL> variable c clob
SQL> exec dbms_utility.expand_sql_text('select ename,sal from emp order by sal desc fetch first row only',:c)

PL/SQL procedure successfully completed.

SQL> set long 10000
SQL> print c

C
--------------------------------------------------------------------------------
SELECT  "A1"."ENAME" "ENAME",
        "A1"."SAL" "SAL"
  FROM  (
         SELECT  "A2"."ENAME" "ENAME",
                 "A2"."SAL" "SAL",
                 "A2"."SAL" "rowlimit_$_0",
                 ROW_NUMBER() OVER (ORDER BY "A2"."SAL" DESC ) "rowlimit_$$_rownumber"
           FROM  "SCOTT"."EMP" "A2"
        ) "A1"
  WHERE "A1"."rowlimit_$$_rownumber"<=1
  ORDER BY "A1"."rowlimit_$_0" DESC



SY.
...
Рейтинг: 0 / 0
двойной select
    #39744352
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYИз серии о сусликах (...)Опаньки..
Получается, FETCH FIRST .. - это даже хуже чем старое-доброе top-N ?
...
Рейтинг: 0 / 0
двойной select
    #39744359
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--Eugene--Опаньки..
Получается, FETCH FIRST .. - это даже хуже чем старое-доброе top-N ?

Да нет:

Код: plsql
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.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
SQL> EXPLAIN PLAN FOR
  2  SELECT *
  3    FROM (SELECT * FROM employees ORDER BY employee_id)
  4    WHERE ROWNUM < 11;

Explained.

SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------
Plan hash value: 460450477

-------------------------------------------------------------------------------------
| Id  | Operation               | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |           |    10 |  1330 |     4  (25)| 00:00:01 |
|*  1 |  COUNT STOPKEY          |           |       |       |            |          |
|   2 |   VIEW                  |           |   107 | 14231 |     4  (25)| 00:00:01 |
|*  3 |    SORT ORDER BY STOPKEY|           |   107 |  7704 |     4  (25)| 00:00:01 |
|   4 |     TABLE ACCESS FULL   | EMPLOYEES |   107 |  7704 |     3   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(ROWNUM<11)
   3 - filter(ROWNUM<11)

17 rows selected.

SQL> EXPLAIN PLAN FOR
  2  SELECT * FROM employees ORDER BY employee_id FETCH FIRST 10 ROWS ONLY;

Explained.

SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------
Plan hash value: 2698234872

--------------------------------------------------------------------------------------
| Id  | Operation                | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |           |    10 |  1590 |     4  (25)| 00:00:01 |
|*  1 |  VIEW                    |           |    10 |  1590 |     4  (25)| 00:00:01 |
|*  2 |   WINDOW SORT PUSHED RANK|           |   107 |  7704 |     4  (25)| 00:00:01 |
|   3 |    TABLE ACCESS FULL     | EMPLOYEES |   107 |  7704 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------------------


PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("from$_subquery$_002"."rowlimit_$$_rownumber"<=10)
   2 - filter(ROW_NUMBER() OVER ( ORDER BY "EMPLOYEES"."EMPLOYEE_ID")<=10)

16 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
двойной select
    #39744374
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И что ты показал?
Ну покажи на миллионе записей
Там обычный COUNT STOPKEY уделает ROW_NUMBER() OVER (ORDER BY "A2"."SAL" DESC )

Это в общем-то давно известно
...
Рейтинг: 0 / 0
двойной select
    #39744385
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав ЛюбомудровЭто в общем-то давно известно

Воможно. Я думал и WINDOW SORT PUSHED RANK и SORT ORDER BY STOPKEY остановят сортировку после первых N.

SY.
...
Рейтинг: 0 / 0
двойной select
    #39744401
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Насколько помню, там речь не про остановку сортировки
COUNT STOPKEY хранит (ROWNUM<11) всего 10 последних максимальных/минимальных значений -- вся сортировка делается не более чем с 10 максимальными/минимальными значениями
WINDOW SORT PUSHED RANK вроде должен делать тоже самое, но в большинстве случаев это не работает и идет полная сортировка по окну

Да вроде, обсуждалось неоднократно

Или это у меня "волшебные пузырьки"?
...
Рейтинг: 0 / 0
двойной select
    #39744423
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав ЛюбомудровИ что ты показал?
Ну покажи на миллионе записей
Там обычный COUNT STOPKEY уделает ROW_NUMBER() OVER (ORDER BY "A2"."SAL" DESC )

Это в общем-то давно известно

600тысч, для rownun<10 разница незаметна

....
stax
...
Рейтинг: 0 / 0
двойной select
    #39744441
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Вячеслав ЛюбомудровНасколько помню, там речь не про остановку сортировки
COUNT STOPKEY хранит (ROWNUM<11) всего 10 последних максимальных/минимальных значений -- вся сортировка делается не более чем с 10 максимальными/минимальными значениями
WINDOW SORT PUSHED RANK вроде должен делать тоже самое, но в большинстве случаев это не работает и идет полная сортировка по окну

Да вроде, обсуждалось неоднократно

Или это у меня "волшебные пузырьки"?WINDOW SORT PUSHED RANK тоже так же работает, другое дело, что она сама по себе сложнее, поэтому и работает чуть дольше. Естественно, я не говорю о "with ties" или всяких RANK
...
Рейтинг: 0 / 0
двойной select
    #39744446
Человек и Кошка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
двойной select
    #39744458
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо,
Но у меня, как правило, получались другие результаты
Может версии были не те, но сложилось стойкое впечатление, что в простых случаях COUNT STOPKEY проще и быстрее WINDOW SORT PUSHED RANK
В более сложных (в запросе кроме аналитики есть еще и общая сортировка) я даже не сомневался в этом
...
Рейтинг: 0 / 0
двойной select
    #39744462
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
StaxВячеслав ЛюбомудровИ что ты показал?
Ну покажи на миллионе записей
Там обычный COUNT STOPKEY уделает ROW_NUMBER() OVER (ORDER BY "A2"."SAL" DESC )
Это в общем-то давно известно
600тысч, для rownun<10 разница незаметна


Не заметна.
Код: plsql
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.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
SQL> create table dropme_t(orderkey not null, payload) as
  2    select decode(mod(rownum,2),0,rownum, -rownum) , rpad('A',1000,'B')
  3      from dual
  4   connect by level <= 1e6
  5  ;

Таблица создана.

--  сбор статистики нужен, чтобы оптимизатор не собирал рекурсивно в динамике - это портит статистику autotrace
SQL> exec dbms_stats.gather_table_stats(user, 'DROPME_T');

Процедура PL/SQL успешно завершена.

SQL> set echo on
SQL> set autotrace traceonly statistics
SQL> select * from (select * from dropme_t order by orderkey) where rownum <= 10;

10 строк выбрано.


Статистика
----------------------------------------------------------
          5  recursive calls
         21  db block gets
      71494  consistent gets
...
          1  sorts (memory)
          0  sorts (disk)
         10  rows processed

SQL> select * from dropme_t order by orderkey fetch first 10 rows only;

10 строк выбрано.


Статистика
----------------------------------------------------------
          2  recursive calls
         22  db block gets
      71497  consistent gets
...
          1  sorts (memory)
          0  sorts (disk)
         10  rows processed

-- теперь с индексом
SQL> create index dropme_t$ord on dropme_t(orderkey);

Индекс создан.

SQL> exec dbms_stats.gather_table_stats(user, 'DROPME_T', cascade=>true);

Процедура PL/SQL успешно завершена.

SQL> select * from (select * from dropme_t order by orderkey) where rownum <= 10;

10 строк выбрано.


Статистика
----------------------------------------------------------
          5  recursive calls
          0  db block gets
          8  consistent gets
...
          0  sorts (memory)
          0  sorts (disk)
         10  rows processed

SQL> select * from dropme_t order by orderkey fetch first 10 rows only;

10 строк выбрано.


Статистика
----------------------------------------------------------
          2  recursive calls
          0  db block gets
          8  consistent gets
...
          0  sorts (memory)
          0  sorts (disk)
         10  rows processed

SQL> set autotrace off
SQL> drop table dropme_t purge;

Таблица удалена.

SQL>

...
Рейтинг: 0 / 0
двойной select
    #39744469
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Заклевали
Пойду дальше "пузырики" лопать
...
Рейтинг: 0 / 0
двойной select
    #39744471
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtenderWINDOW SORT PUSHED RANK тоже так же работает, другое дело, что она сама по себе сложнее, поэтому и работает чуть дольше. Естественно, я не говорю о "with ties" или всяких RANK

Не поленился проверить. Версия 12.1.0.2.0, 2 node RAC на EXADATA:

Код: plsql
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.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
SQL> SELECT  COUNT(*)
  2    FROM  MNY_PROVISION_PART
  3  /

  COUNT(*)
----------
 418423940

SQL> SET TIMING ON
SQL> SELECT CD
  2    FROM  (SELECT CD FROM MNY_PROVISION_PART ORDER BY CD DESC)
  3    WHERE ROWNUM < 11
  4  /

        CD
----------
 442961538
 442961538
 442961538
 442961538
 442961308
 442961308
 442961308
 442961308
 442961308
 442961308

10 rows selected.

Elapsed: 00:04:50.19
SQL> SELECT  CD
  2    FROM  (SELECT CD FROM MNY_PROVISION_PART ORDER BY CD DESC)
  3    WHERE ROWNUM < 11
  4  /

        CD
----------
 442961538
 442961538
 442961538
 442961538
 442961308
 442961308
 442961308
 442961308
 442961308
 442961308

10 rows selected.

Elapsed: 00:04:42.91
SQL> SELECT  CD
  2    FROM  MNY_PROVISION_PART
  3    ORDER BY CD DESC
  4    FETCH FIRST 10 ROWS ONLY
  5  /

        CD
----------
 442961538
 442961538
 442961538
 442961538
 442961308
 442961308
 442961308
 442961308
 442961308
 442961308

10 rows selected.

Elapsed: 00:01:18.55
SQL> 



SY.
...
Рейтинг: 0 / 0
двойной select
    #39744624
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
SY,

прогнал сейчас тесты на 12.1.0.2(не экзадата) и 12.2.0.1(экзадата): по умолчанию "fetch first" был быстрее в 2 раза. Глянул статистики: fetch first на обычном сервере использовал serial direct path reads, а rownum - нет.
На экзадате I/O
fetch first: через cell smart table scan
rownum: через cell multiblock physical read и cell multiblock read request

Очевидно, что rownum своим включением режима оптимизации first rows (_optimizer_rownum_pred_based_fkr - enable the use of first K rows due to rownum predicate), отключает директридсы и смартскан.


Пример с обычным сервером:
Сделал
Код: plsql
1.
alter session set "_serial_direct_read"=always;

и стало примерно одинаково:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
--12.1.0.2
SQL> select * from (select * from TEST_TAB2 order by f1) where rownum<=10;

10 rows selected.

Elapsed: 00:00:05.30

SQL> select * from TEST_TAB2 order by f1 fetch first 10 rows only;

10 rows selected.

Elapsed: 00:00:05.22



Пример с экзадатой:
fetch first: 00:07:57.51
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
SQL> set autot trace stat feed only timing on
SQL> select * from TTT order by CCC fetch first 10 rows only;

10 rows selected.

Elapsed: 00:07:57.51

Statistics
----------------------------------------------------------
         17  recursive calls
         11  db block gets
    8649233  consistent gets
    8637603  physical reads
       1144  redo size
       7460  bytes sent via SQL*Net to client
        552  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
         10  rows processed


rownum c "_optimizer_rownum_pred_based_fkr"=false: 00:06:41.46
Код: plsql
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.
46.
SQL> alter session set "_optimizer_rownum_pred_based_fkr"=false;

Session altered.

SQL> set feed only timing on autot trace stat
SQL> select * from (select * from TTT order by CCC) where rownum<=10;

10 rows selected.

Elapsed: 00:06:41.46

Statistics
----------------------------------------------------------
         11  recursive calls
          3  db block gets
    8641469  consistent gets
    8637300  physical reads
       3960  redo size
       7497  bytes sent via SQL*Net to client
        552  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
         10  rows processed

Global Stats
==============================================================================================================================================================
| Elapsed |   Cpu   |    IO    | Application | Concurrency |  Other   | Fetch | Buffer | Read | Read  | Uncompressed |  Offload   |    Offload     |  Cell   |
| Time(s) | Time(s) | Waits(s) |  Waits(s)   |  Waits(s)   | Waits(s) | Calls |  Gets  | Reqs | Bytes |    Bytes     | Elig Bytes | Returned Bytes | Offload |
==============================================================================================================================================================
|     401 |     388 |       10 |        0.01 |        0.00 |     2.44 |     2 |     9M | 599K |  66GB |         66GB |       66GB |           63GB |   4.87% |
==============================================================================================================================================================

SQL Plan Monitoring Details (Plan Hash Value=306186833)
=====================================================================================================================================================================================
| Id |           Operation            |    Name    |  Rows   | Cost |   Time    | Start  | Execs |   Rows   | Read | Read  |  Mem  | Activity |           Activity Detail           |
|    |                                |            | (Estim) |      | Active(s) | Active |       | (Actual) | Reqs | Bytes | (Max) |   (%)    |             (# samples)             |
=====================================================================================================================================================================================
|  0 | SELECT STATEMENT               |            |         |      |         1 |   +401 |     1 |       10 |      |       |     . |          |                                     |
|  1 |   COUNT STOPKEY                |            |         |      |         1 |   +401 |     1 |       10 |      |       |     . |          |                                     |
|  2 |    VIEW                        |            |    265M |  17M |         1 |   +401 |     1 |       10 |      |       |     . |          |                                     |
|  3 |     SORT ORDER BY STOPKEY      |            |    265M |  17M |       399 |     +3 |     1 |       10 |      |       |  6144 |    71.00 | Cpu (284)                           |
|  4 |      TABLE ACCESS STORAGE FULL | TTT        |    265M |   2M |       401 |     +1 |     1 |     266M | 599K |  66GB |   5MB |    29.00 | Cpu (99)                            |
|    |                                |            |         |      |           |        |       |          |      |       |       |          | cell single block physical read (2) |
|    |                                |            |         |      |           |        |       |          |      |       |       |          | cell smart table scan (15)          |
=====================================================================================================================================================================================



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


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