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
Jul 282015
 

Godiva, pojďmě si představit další funkci z balíčku funkcí, které tu jsou nově v 12.1c – APPROX_COUNT_DISTINCT. Jak název napovídá funkce vrátí počet distinctních hodnot a slovo APPROX znamená, že je to “asi tak nějak” :) Výměnou za nějakou tu nepřesnost dostaneme mnohonásobné zrychlení. Takže hurá na nějaký test a další informace dále :

CREATE TABLE TEST_APROX(
ID NUMBER(30) PRIMARY KEY,
TEST_RANDOM   NUMBER,
TEST_1_100    NUMBER,
TEST_1_2_3    NUMBER,
TEST_1_25000  NUMBER,
TEST_10_1     NUMBER
);

A ještě je třebas jí naplnit:

begin
for i in 0..100 loop
INSERT INTO TEST_APROX
  SELECT ROWNUM+(i*30000) AS ID,
  dbms_random.value AS TEST_RANDOM,
  MOD(rownum,100)   AS TEST_1_100,
  CASE WHEN ROWNUM=15555 THEN 1
       WHEN ROWNUM=15556 THEN 2
  ELSE 3 END        AS TEST_1_2_3,
  CASE WHEN ROWNUM<25000 THEN 1 
     ELSE ROWNUM END AS TEST_1_25000,
  CASE WHEN MOD(ROWNUM,10)<>2 THEN MOD(ROWNUM,10)
  ELSE 1 END AS TEST_10_1
 FROM dual CONNECT BY LEVEL <=30000;
 end loop;
end;

Tak nějak nějaký vzorek dat, některá lehce zkosená některá náhodná. Doporučuji případně ještě napočítat statistiky během CTASu se sice nově napočítávají, ale takhle v LOOPu to nezafunguje, bohužel.  Mě to vychází nějak takto:

Sloupec Popis dat DISTINCT APR CNT DIS APR CNT DIS result Chyba
ID Čísla od 1 do 3030000 2,8 (jedeme po indexu) 1s 2975859 1,78%
TEST_RANDOM Náhodná čísla cca 19s 1s 2986718 1,42%
TEST_1_100 Čísla od 0 do 99, každé 30300x 2s pod 1s 100 0%
TEST_1_2_3 čísla 1,2 101x číslo 3 3029798x pod 1s pod 1s 3 0%
TEST_1_25000 1x 2524899,101x 25000-30000 1s-2s pod 1s 5018 3,2%
TEST_10_1 30300x 0,3-9, 606000x 1 1s-2s pod 1s 9 0%

Takže nějaký závěr: narozdíl od DISTINCT se závislost na datech neprojeví zpomalením, ale na nepřesnosti. Což je hodně sympatické, bohužel jsem podcenil svůj komp a zrychení je vidět de-facto jen ve dvou případech, ale i tak je vidět že o proti normálnímu COUNTU hraje APPROX_COUNT_DISTINCT naprosto jinou ligu :) A to i proti indexu je daleko rychlejšejší. V exekučním plánu to vypadá nějak takto:

Aprox exekuční plán

Aprox exekuční plán

Nicméně ačkoliv to ukazuje sort mě se na tomhle příkladu nic reálně nesortovalo, jestli to takhle zafunguje budeme muset zjistit ;) Enjoy APPROX_COUNT_DISTINCT !

 Posted by at 22:42

 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>