Warning: Declaration of Suffusion_MM_Walker::start_el(&$output, $item, $depth, $args) should be compatible with Walker_Nav_Menu::start_el(&$output, $item, $depth = 0, $args = Array, $id = 0) in /DISK2/WWW/plsql.cz/www/wp-content/themes/suffusion/library/suffusion-walkers.php on line 0
Oct 052014
 

Pokračování krátkého zkoumání jaké hodnoty se objevují ve sloupci STARTS v pohledu V$SQL_PLAN_MONITOR. Předchozí díl se věnoval počtu startů u tabulky, která není partišnovaná a dnešní díl se tedy bude věnovat tomuto sloupci u partitiovaných tabulek. Další díl budu věnovat paralelním selectům a pak se uvidí ;) Protože je to dost zajímavý sloupec a těch kombinací a zajímavých operací je spousty, ale muj čas je omezen. Takže hurá na to!

Takže pojďme udělat rovnou tabulku s nějakýma partitions:

create table tbl_range (a_column)
PARTITION BY RANGE(a_column)
(
PARTITION p1 VALUES LESS THAN(1),
PARTITION p2 VALUES LESS THAN(2),
PARTITION p3 VALUES LESS THAN(3),
PARTITION p4 VALUES LESS THAN(4),
PARTITION p5 VALUES LESS THAN(5),
PARTITION p6 VALUES LESS THAN(6)
) as
select mod(rownum,6) from dual connect by level<1001;

A nyní select:

select /*+ MONITOR */ * from tbl_range;

Asi by člověka napadlo, že bude mít tolik startů, kolik má partitions. A přesně tak tomu je, ovšem s menším ale – protože první SQL Developer fetchne pouze 50 řádků (defalutní hodnota), takže je třeba proscrollovat a dostáváme počet startů rovných 6ti:

(počet startů – range)

Nebylo zajímavé, že? Prozradím, že s INLIST a HASH partitions to funguje naprosto stejně, daleko zajímavější je INVERVAL partitions. A vlastně důvodu proč tenhle článek vzniknul:

CREATE TABLE tbl_rang_i (a_column NUMBER(10))
PARTITION BY RANGE(a_column)
INTERVAL(13)
(PARTITION base VALUES LESS THAN (0)
);

A nyní insertneme nějaká data:

insert into tbl_rang_i
select rownum from dual connect by level<=400 union all
select rownum+800 from dual connect by level<=400;

Konkrétně je to 800 řádků. Čísla od 1..400 a 800..1200. Takže se podívejme, kolik má tabulka partitions:

select owner,table_name,partition_count from all_part_tables where lower(table_name)='tbl_rang_i';

Počet partitions v tomhle view je 1048575, překvani? Taky jsem nedávno byl ;) Ale Oracle v tomhle view pro tabulky na kterých je interval partitioning udává Oracle vždy číslo 1048575. Číslo není nějak moc magické, udává maximální počet partitions, který tabulka může být.  Takže zkusime jiné view:

select count(*) from all_tab_partitions where lower(table_name)='tbl_rang_i';

Je jich 64. Lehce podezřele binárně kulaté číslo ;) Ale to je jen náhoda – začínání od 0 a dva intervaly v rozmezí 1..400 a 800..1200 (takže něco jako select 2*(ceil(400/13))+1+1 from dual).  A nyní konečně počet startů:

select /*+ MONITOR */ * from tbl_rang_i;

(počet startů – range-interval)

94. Což je lehce podezřelé číslo. Speciálně, když čekáte až Vám doběhne select a full table scan nad tabulkou co má 64 partitions přesáhne 65 a vesele si pokračuje. Nicméně po několika mých testech jsem doše k tomu, že Oracle pro interval partitions připočítává do STARTS i “mezery”. Tedy výpočet pro tento případ je select ceil(1200/13)+1 from dual tzn. 94 (jedna je pro BASE partition).

Inu počty startů:

  • Pro range, list, hash – vždy počet partitions
  • Pro range-interval – (spread mezi LOW a HIGH hodnotou v partiton sloupci) / intervalem partišnování (případně +1 pokud base partition je mimo)
  • Precedenci berou “nižší karta” tedy full scanu nad supartišnovanou tabulkou je ve sloupcu STARTS počet čtených subpartitions.

Bohužel vzhledem k mému omezenému času tento článek končím, ale napadají mi daleko zajímavější scénáře – systém a referenční partitioning, partition wise-join a počet startů..

 Posted by at 11:52

 Leave a Reply

(required)

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>