Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Oracle |
![]() ![]() |
petrovichvanya Member Откуда: Сообщений: 122 |
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 ? |
7 дек 18, 11:41 [21756794] Ответить | Цитировать Сообщить модератору |
viking_dooh Member Откуда: Сообщений: 12 |
petrovichvanya, Для 12с: select * from brsactions a where a.contractid = '3280915' and a.actioncodeid in (17025310, 17025339, 17050320) order by a.operdate desc fetch first row only |
7 дек 18, 11:47 [21756807] Ответить | Цитировать Сообщить модератору |
Stax Member Откуда: Ukraine,Lviv Сообщений: 2958 |
Для семерки если есть индекс по operdate и operdate is not null 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 |
||
7 дек 18, 12:16 [21756854] Ответить | Цитировать Сообщить модератору |
petrovichvanya Member Откуда: Сообщений: 122 |
оба варианта не подошли, жаль( |
7 дек 18, 12:19 [21756865] Ответить | Цитировать Сообщить модератору |
-2- Member Откуда: Сообщений: 15330 |
|
||
7 дек 18, 12:35 [21756901] Ответить | Цитировать Сообщить модератору |
Stax Member Откуда: Ukraine,Lviv Сообщений: 2958 |
petrovichvanya, CONTRACTID уникальное 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 |
7 дек 18, 12:55 [21756929] Ответить | Цитировать Сообщить модератору |
SY Member Откуда: Middlebury, CT USA Сообщений: 10120 |
Из серии о сусликах: 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. |
||
7 дек 18, 15:15 [21757139] Ответить | Цитировать Сообщить модератору |
--Eugene-- Member Откуда: Боярышник Сообщений: 2188 |
Получается, FETCH FIRST .. - это даже хуже чем старое-доброе top-N? |
||
7 дек 18, 15:31 [21757157] Ответить | Цитировать Сообщить модератору |
SY Member Откуда: Middlebury, CT USA Сообщений: 10120 |
Да нет: 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. |
||
7 дек 18, 15:40 [21757169] Ответить | Цитировать Сообщить модератору |
Вячеслав Любомудров Member Откуда: Владивосток Сообщений: 18525 |
И что ты показал? Ну покажи на миллионе записей Там обычный COUNT STOPKEY уделает ROW_NUMBER() OVER (ORDER BY "A2"."SAL" DESC ) Это в общем-то давно известно |
7 дек 18, 15:47 [21757189] Ответить | Цитировать Сообщить модератору |
SY Member Откуда: Middlebury, CT USA Сообщений: 10120 |
Воможно. Я думал и WINDOW SORT PUSHED RANK и SORT ORDER BY STOPKEY остановят сортировку после первых N. SY. |
||
7 дек 18, 15:54 [21757204] Ответить | Цитировать Сообщить модератору |
Вячеслав Любомудров Member Откуда: Владивосток Сообщений: 18525 |
Насколько помню, там речь не про остановку сортировки COUNT STOPKEY хранит (ROWNUM<11) всего 10 последних максимальных/минимальных значений -- вся сортировка делается не более чем с 10 максимальными/минимальными значениями WINDOW SORT PUSHED RANK вроде должен делать тоже самое, но в большинстве случаев это не работает и идет полная сортировка по окну Да вроде, обсуждалось неоднократно Или это у меня "волшебные пузырьки"? |
7 дек 18, 16:03 [21757226] Ответить | Цитировать Сообщить модератору |
Stax Member Откуда: Ukraine,Lviv Сообщений: 2958 |
600тысч, для rownun<10 разница незаметна .... stax |
||
7 дек 18, 16:23 [21757266] Ответить | Цитировать Сообщить модератору |
Sayan Malakshinov Member Откуда: Мск Сообщений: 5780 |
|
||
7 дек 18, 16:40 [21757308] Ответить | Цитировать Сообщить модератору |
Человек и Кошка Member Откуда: настоящему индейцу завсегда везде ништяк (с) Сообщений: 830 |
Вячеслав Любомудров, Какой запрос правильней и быстрее? |
7 дек 18, 16:44 [21757317] Ответить | Цитировать Сообщить модератору |
Вячеслав Любомудров Member Откуда: Владивосток Сообщений: 18525 |
Спасибо, Но у меня, как правило, получались другие результаты ![]() Может версии были не те, но сложилось стойкое впечатление, что в простых случаях COUNT STOPKEY проще и быстрее WINDOW SORT PUSHED RANK В более сложных (в запросе кроме аналитики есть еще и общая сортировка) я даже не сомневался в этом |
7 дек 18, 16:55 [21757342] Ответить | Цитировать Сообщить модератору |
andrey_anonymous Member Откуда: Москва Сообщений: 18668 |
Не заметна.
|
|||||
7 дек 18, 17:04 [21757355] Ответить | Цитировать Сообщить модератору |
Вячеслав Любомудров Member Откуда: Владивосток Сообщений: 18525 |
Заклевали ![]() Пойду дальше "пузырики" лопать ![]() |
7 дек 18, 17:07 [21757365] Ответить | Цитировать Сообщить модератору |
SY Member Откуда: Middlebury, CT USA Сообщений: 10120 |
Не поленился проверить. Версия 12.1.0.2.0, 2 node RAC на EXADATA: 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. |
||
7 дек 18, 17:10 [21757368] Ответить | Цитировать Сообщить модератору |
Sayan Malakshinov Member Откуда: Мск Сообщений: 5780 |
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), отключает директридсы и смартскан. Пример с обычным сервером: Сделал alter session set "_serial_direct_read"=always;и стало примерно одинаково: --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 Пример с экзадатой:
Так что по большому счету разницы нет и в случае со сложным запросом где реально работает ALL_ROWS разницы особой не будет. А для простых запросов, но по большим таблицам, там где реально нужна оптимизация ввода/вывода, там FKR портит всю картину, т.к. отключает эти оптимизации. |
||
8 дек 18, 00:59 [21757716] Ответить | Цитировать Сообщить модератору |
Все форумы / Oracle | ![]() |