Oracle
 sql >> डेटाबेस >  >> RDS >> Oracle

विंडो फ़ंक्शन SORT महंगा है, क्या हम इसे दूर कर सकते हैं?

विश्लेषणात्मक फ़ंक्शन प्रदर्शन अनुक्रमणिका स्तंभ क्रम पर निर्भर हो सकता है। इंडेक्स को (ACCTNUM,DEPT_NUM) . से बदलना करने के लिए (DEPT_NUM,ACCTNUM) लागत कम कर सकता है और अस्थायी टेबलस्पेस की आवश्यकता को दूर कर सकता है।

partition by COL_2 order by COL_1 => INDEX FAST FULL SCAN|WINDOW SORT PUSHED RANK
partition by COL_1 order by COL_2 => INDEX FULL SCAN|WINDOW NOSORT

INDEX FAST FULL SCAN तेज़ मल्टी-ब्लॉक IO का उपयोग करता है, लेकिन इसके लिए डेटा को सॉर्ट करना और सॉर्ट क्षेत्र के लिए संभवतः अस्थायी टेबलस्पेस की भी आवश्यकता होती है।

INDEX FULL SCAN धीमे सिंगल-ब्लॉक IO का उपयोग करता है लेकिन यह डेटा को क्रम में लौटाता है और सॉर्टिंग से बचता है।

नमूना स्कीमा और डेटा

--drop table mytable;
create table mytable(dept_num number not null, acctnum number not null
    ,a number, b number, c number, d number, e number);
insert into mytable
select 1 dept_num, 1 acctnum, 0,0,0,0,0 from dual union all
select 1 dept_num, 2 acctnum, 0,0,0,0,0 from dual union all
select 1 dept_num, 3 acctnum, 0,0,0,0,0 from dual union all
select 2 dept_num, 1 acctnum, 0,0,0,0,0 from dual union all
select 2 dept_num, 2 acctnum, 0,0,0,0,0 from dual union all
select 3 dept_num, 1 acctnum, 0,0,0,0,0 from dual;
--Create 600K similar rows.
insert into mytable
  select dept_num + rownumber*3, acctnum, a,b,c,d,e
  from mytable
  cross join (select level rownumber from dual connect by level <= 100000);
begin
    dbms_stats.gather_table_stats(user, 'mytable');
end;
/

(ACCTNUM,DEPT_NUM) =विंडो सॉर्ट पुश रैंक

create index mytable_idx on mytable(acctnum, dept_num);

explain plan for
select dept_num, acctnum from
(
    select dept_num, acctnum
        ,row_number() over (partition by dept_num order by acctnum) as row_identifier
    from mytable
)
where row_identifier between 1 and 10;

select * from table(dbms_xplan.display);

Plan hash value: 952182109

------------------------------------------------------------------------------------------------
| Id  | Operation                | Name        | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |             |   600K|    22M|       |  1625   (3)| 00:00:23 |
|*  1 |  VIEW                    |             |   600K|    22M|       |  1625   (3)| 00:00:23 |
|*  2 |   WINDOW SORT PUSHED RANK|             |   600K|  4687K|  9424K|  1625   (3)| 00:00:23 |
|   3 |    INDEX FAST FULL SCAN  | MYTABLE_IDX |   600K|  4687K|       |   239   (3)| 00:00:04 |
------------------------------------------------------------------------------------------------

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

   1 - filter("ROW_IDENTIFIER">=1 AND "ROW_IDENTIFIER"<=10)
   2 - filter(ROW_NUMBER() OVER ( PARTITION BY "DEPT_NUM" ORDER BY "ACCTNUM")<=10)

(DEPT_NUM,ACCTNUM) =विंडो NOSORT

drop index mytable_idx;
create index mytable_idx on mytable(dept_num, acctnum);

explain plan for
select dept_num, acctnum from
(
    select dept_num, acctnum
        ,row_number() over (partition by dept_num order by acctnum) as row_identifier
    from mytable
)
where row_identifier between 1 and 10;

select * from table(dbms_xplan.display);

Plan hash value: 1773829932

---------------------------------------------------------------------------------
| Id  | Operation         | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |             |   600K|    22M|   792   (2)| 00:00:12 |
|*  1 |  VIEW             |             |   600K|    22M|   792   (2)| 00:00:12 |
|*  2 |   WINDOW NOSORT   |             |   600K|  4687K|   792   (2)| 00:00:12 |
|   3 |    INDEX FULL SCAN| MYTABLE_IDX |   600K|  4687K|   792   (2)| 00:00:12 |
---------------------------------------------------------------------------------

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

   1 - filter("ROW_IDENTIFIER">=1 AND "ROW_IDENTIFIER"<=10)
   2 - filter(ROW_NUMBER() OVER ( PARTITION BY "DEPT_NUM" ORDER BY 
              "ACCTNUM")<=10)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ओरेकल:क्या ट्रिगर में भूमिका बनाना संभव है?

  2. MyBatis में Oracle db . में इनपुट परम सूची<T> के साथ बड़ी संख्या में पंक्तियों को अपडेट करने का सबसे तेज़ तरीका

  3. क्या Oracle में किसी उपयोगकर्ता द्वारा उपयोग किए जाने वाले संसाधनों को थ्रॉटल या सीमित करने का कोई तरीका है?

  4. Oracle को पंक्ति मिलती है जहाँ स्तंभ मान बदल जाता है

  5. टेबल पर भौतिकीकृत दृश्य लॉग से फ़िल्टर कॉलम का उपयोग नहीं कर सकता