sql >> Database teknologi >  >> RDS >> Oracle

Vinduesfunktioner SORTERE dyre, kan vi overkomme det?

Den analytiske funktions ydeevne kan afhænge af rækkefølgen af ​​indekskolonnen. Ændring af indekset fra (ACCTNUM,DEPT_NUM) til (DEPT_NUM,ACCTNUM) kan sænke omkostningerne og fjerne behovet for midlertidig tablespace.

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 bruger hurtigere multi-blok IO, men det kræver også sortering af data og muligvis midlertidig tablespace for sorteringsområdet.

INDEX FULL SCAN bruger langsommere enkelt-blok IO, men det returnerer dataene i rækkefølge og undgår sortering.

Eksempel på skema og data

--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) =WINDOW SORT PUSHED RANK

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) =WINDOW 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. Kan vi forbinde ekstern MySQL-database i Android ved hjælp af JDBC?

  2. Sådan gemmer du en IP i mySQL

  3. Bestil før CONCAT_WS

  4. Betinget SQL Query Assistance