Databázové Aplikace Slidy ke cvičení DBI026, část 2 KSI MFF UK Verze
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Vytvoření demo tabulek EMP a DEPT Pokud existovaly, jsou sktiptem nejprve smazány příkazy –DROP TABLE DEPT; –DROP TABLE EMP;
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Vytvoření tabulky PLAN_TABLE pro ukládání plánů provedení Zapnutí AUTOTRACE v SQL*Plus –SET AUTOTRACE ON Případné vypnutí AUTOTRACE –SET AUTOTRACE OFF
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle SQL> select * from dept; DEPTNO DNAME LOC ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON Execution Plan SELECT STATEMENT Optimizer=CHOOSE 1 0 TABLE ACCESS (FULL) OF 'DEPT‚ Statistics recursive calls 0 db block gets 23 consistent gets 0 physical reads 0 redo size 505 bytes sent via SQL*Net to client 495 bytes received via SQL*Net from … 4 SQL*Net roundtrips to/from client 2 sorts (memory) 0 sorts (disk) 4 rows processed Průchod tabulkou DEPT bez použití indexů
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Spojení obou tabulek EMP a DEPT SQL> SELECT Emp.*, Dept.Loc 2 FROM Dept, Emp 3 WHERE Dept.DeptNo=Emp.DeptNo; Execution Plan SELECT STATEMENT Optimizer=CHOOSE 1 0 MERGE JOIN 2 1 SORT (JOIN) 3 2 TABLE ACCESS (FULL) OF 'EMP‚ 4 1 SORT (JOIN) 5 4 TABLE ACCESS (FULL) OF 'DEPT' Statistics recursive calls 0 db block gets 33 consistent gets 0 physical reads 0 redo size 1239 bytes sent via SQL*Net to client 495 bytes received via SQL*Net from … 4 SQL*Net roundtrips to/from client 4 sorts (memory) 0 sorts (disk) 14 rows processed Setřídění obou tabulek a následný MERGE (velmi neefektivní spojení)
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Jaké na tabulkách existují omezení? –SELECT Constraint_name, Constraint_type, Table_name, Search_condition FROM User_constraints WHERE Table_name IN ('DEPT','EMP'); Jen nepojmenovaná kontrola NOT NULL sloupce EMP.EmpNo –CONSTRAINT_NAME C TABLE_NAME SEARCH_CONDITION SYS_C C EMP "EMPNO" IS NOT NULL
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Přidáme primární klíče a cizí klíč –ALTER TABLE EMP ADD CONSTRAINT EMP_PK PRIMARY KEY (EmpNo); –ALTER TABLE DEPT ADD CONSTRAINT DEPT_PK PRIMARY KEY (DeptNo); –ALTER TABLE EMP ADD CONSTRAINT EMP_FK_DEPT FOREIGN KEY (DeptNo) REFERENCES DEPT(EmpNo) ON DELETE SET NULL; Existující omezení: –CONSTRAINT_NAME C TABLE_NAME SEARCH_CONDITION EMP_PK P EMP DEPT_PK P DEPT EMP_FK_DEPT R DEPT SYS_C C EMP "EMPNO" IS NOT NULL
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Spojení obou tabulek EMP a DEPT SQL> SELECT Emp.*, Dept.Loc 2 FROM Dept, Emp 3 WHERE Dept.DeptNo=Emp.DeptNo; Execution Plan SELECT STATEMENT Optimizer=CHOOSE 1 0 NESTED LOOPS 2 1 TABLE ACCESS (FULL) OF 'EMP‚ 3 1 TABLE ACCESS (BY INDEX ROWID) OF 'DEPT' 4 3 INDEX (UNIQUE SCAN) OF 'DEPT_PK' (UNIQUE) Statistics recursive calls 0 db block gets 81 consistent gets 0 physical reads 0 redo size 1346 bytes sent via SQL*Net to client 495 bytes received via SQL*Net from … 4 SQL*Net roundtrips to/from client 8 sorts (memory) 0 sorts (disk) 14 rows processed Vnořené cykly, pro každého zaměstnance se dohledá oddělení přes index
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Kteří zaměstnanci jsou v New Yorku? SQL> SELECT * FROM Emp 2 WHERE DeptNo=( SELECT DeptNo FROM Dept WHERE Loc='NEW YORK' ); Execution Plan SELECT STATEMENT Optimizer=CHOOSE 1 0 FILTER 2 1 TABLE ACCESS (FULL) OF 'EMP‚ 3 1 TABLE ACCESS (FULL) OF 'DEPT‚ Statistics recursive calls 0 db block gets 52 consistent gets 0 physical reads 0 redo size 764 bytes sent via SQL*Net to client 495 bytes received via SQL*Net from … 4 SQL*Net roundtrips to/from client 4 sorts (memory) 0 sorts (disk) 3 rows processed Spojit vše se vším (?) a výsledné řádky filtrovat
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Kteří zaměstnanci jsou v New Yorku? Pokus s IN místo = … SQL> SELECT * FROM Emp 2 WHERE DeptNo IN ( SELECT DeptNo FROM Dept WHERE Loc='NEW YORK' ); Execution Plan SELECT STATEMENT Optimizer=CHOOSE 1 0 NESTED LOOPS 2 1 TABLE ACCESS (FULL) OF 'EMP‘ 3 1 TABLE ACCESS (BY INDEX ROWID) OF 'DEPT' 4 3 INDEX (UNIQUE SCAN) OF 'DEPT_PK' (UNIQUE) Statistics recursive calls 0 db block gets 25 consistent gets 0 physical reads 0 redo size 764 bytes sent via SQL*Net to client 495 bytes received via SQL*Net from … 4 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 3 rows processed Stejně jako join, odpovídající řádky se dohledají ve výsledku
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Vytvoříme ještě index přes cizí klíč … –CREATE INDEX Emp_DeptNo_Inx ON Emp(DeptNo); … a bitmapový index přes umístění oddělení –CREATE BITMAP INDEX Dept_Loc_Inx ON Dept(Loc);
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Kteří zaměstnanci jsou v New Yorku? SQL> SELECT * FROM Emp 2 WHERE DeptNo=( SELECT DeptNo FROM Dept WHERE Loc='NEW YORK' ); Execution Plan SELECT STATEMENT Optimizer=CHOOSE 1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMP' 2 1 INDEX (RANGE SCAN) OF 'EMP_DEPTNO_INX' (NON-UNIQUE) 3 2 TABLE ACCESS (FULL) OF 'DEPT' Statistics recursive calls 0 db block gets 11 consistent gets 0 physical reads 0 redo size 770 bytes sent via SQL*Net to client 495 bytes received via SQL*Net from … 4 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 3 rows processed V Dept se najde odpovídající řádka a k ní se přes index dohledají zaměstnanci
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Kteří zaměstnanci jsou v New Yorku? Pokus s IN místo = … SQL> SELECT * FROM Emp 2 WHERE DeptNo IN ( SELECT DeptNo FROM Dept WHERE Loc='NEW YORK' ); Execution Plan SELECT STATEMENT Optimizer=CHOOSE 1 0 NESTED LOOPS 2 1 TABLE ACCESS (FULL) OF 'EMP‘ 3 1 TABLE ACCESS (BY INDEX ROWID) OF 'DEPT' 4 3 INDEX (UNIQUE SCAN) OF 'DEPT_PK' (UNIQUE) Statistics recursive calls 0 db block gets 25 consistent gets 0 physical reads 0 redo size 764 bytes sent via SQL*Net to client 495 bytes received via SQL*Net from … 4 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 3 rows processed Stále stejně jako join, odpovídající řádky se dohledají ve výsledku
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Opět spojení obou tabulek … SQL> SELECT Emp.*, Dept.Loc 2 FROM Dept, Emp 3 WHERE Dept.DeptNo=Emp.DeptNo; Execution Plan SELECT STATEMENT Optimizer=CHOOSE 1 0 NESTED LOOPS 2 1 TABLE ACCESS (FULL) OF 'EMP‚ 3 1 TABLE ACCESS (BY INDEX ROWID) OF 'DEPT' 4 3 INDEX (UNIQUE SCAN) OF 'DEPT_PK' (UNIQUE) Statistics recursive calls 0 db block gets 24 consistent gets 0 physical reads 0 redo size 1352 bytes sent via SQL*Net to client 495 bytes received via SQL*Net from … 4 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 14 rows processed Vnořené cykly, pro každého zaměstnance se dohledá oddělení. Druhá tabulka ve FROM je řídící.
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Opět spojení obou tabulek … prohodíme pořadí tabulek ve FROM SQL> SELECT Emp.*, Dept.Loc 2 FROM Emp, Dept 3 WHERE Dept.DeptNo=Emp.DeptNo; Execution Plan SELECT STATEMENT Optimizer=CHOOSE 1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMP' 2 1 NESTED LOOPS 3 2 TABLE ACCESS (FULL) OF 'DEPT‚ 4 2 INDEX (RANGE SCAN) OF 'EMP_DEPTNO_INX' (NON-UNIQUE) Statistics recursive calls 0 db block gets 13 consistent gets 0 physical reads 0 redo size 1280 bytes sent via SQL*Net to client 495 bytes received via SQL*Net from … 4 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 14 rows processed Vnořené cykly, pro každé oddělení se dohledají zaměstnanci. Druhá tabulka ve FROM je opět řídící. Pokud by index přes cizí klíč neexistoval, byl by výsledek shodný s opačným pořadím.
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Zkusíme COST-BASED optimalizaci … Vytvoříme statistiky na tabulkách, optimalizátor v režimu CHOOSE bude CB optimalizaci upřednostňovat –ANALYZE TABLE Emp COMPUTE STATISTICS; –ANALYZE TABLE Dept COMPUTE STATISTICS;
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Opět spojení obou tabulek, tentokrát s CB optimalizací … SQL> SELECT Emp.*, Dept.Loc 2 FROM Emp, Dept 3 WHERE Dept.DeptNo=Emp.DeptNo; Execution Plan SELECT STATEMENT Optimizer=CHOOSE (Cost=5 Card=14 Bytes=574) 1 0 HASH JOIN (Cost=5 Card=14 Bytes=574) 2 1 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=14 Bytes=448) 3 1 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=4 Bytes=36) Statistics recursive calls 0 db block gets 15 consistent gets 0 physical reads 0 redo size 1279 bytes sent via SQL*Net to client 495 bytes received via SQL*Net from … 4 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 14 rows processed Dat je tak málo, že se přístup přes indexy vůbec nevyplatí …
DBI026 -DB Aplikace - MFF UK Přidáme hint FIRST_ROWS a … Optimalizace v Oracle A opět spojení obou tabulek, minimalizujeme cenu nalezení první řádky … SQL> SELECT --+ FIRST_ROWS 2 Emp.*, Dept.Loc 3 FROM Emp, Dept 4 WHERE Dept.DeptNo=Emp.DeptNo; Execution Plan SELECT STATEMENT Optimizer=HINT: FIRST_ROWS (Cost=8 Card=14 Bytes=574) 1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMP' (Cost=1 Card=4 Bytes=128) 2 1 NESTED LOOPS (Cost=8 Card=14 Bytes=574) 3 2 VIEW OF 'index$_join$_002' (Cost=4 Card=4 Bytes=36) 4 3 HASH JOIN 5 4 BITMAP CONVERSION (TO ROWIDS) 6 5 BITMAP INDEX (FULL SCAN) OF 'DEPT_LOC_INX' 7 4 INDEX (FAST FULL SCAN) OF 'DEPT_PK' (UNIQUE) (Cost=1 Card=4 Bytes=36) 8 2 INDEX (RANGE SCAN) OF 'EMP_DEPTNO_INX' (NON-UNIQUE) Statistics recursive calls 0 db block gets 10 consistent gets 0 physical reads 0 redo size 1280 bytes sent via SQL*Net to client 495 bytes received via SQL*Net from … 4 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 14 rows processed
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle A opět spojení obou tabulek, minimalizujeme cenu nalezení prvních 5 řádek … SQL> SELECT --+ FIRST_ROWS(5) 2 Emp.*, Dept.Loc 3 FROM Emp, Dept 4 WHERE Dept.DeptNo=Emp.DeptNo; Execution Plan SELECT STATEMENT Optimizer=HINT: FIRST_ROWS (Cost=4 Card=5 Bytes=205) 1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMP' (Cost=1 Card=4 Bytes=128) 2 1 NESTED LOOPS (Cost=4 Card=5 Bytes=205) 3 2 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=2 Bytes=18) 4 2 INDEX (RANGE SCAN) OF 'EMP_DEPTNO_INX' (NON-UNIQUE) Statistics recursive calls 0 db block gets 13 consistent gets 0 physical reads 0 redo size 1280 bytes sent via SQL*Net to client 495 bytes received via SQL*Net from … 4 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 14 rows processed Přidáme hint FIRST_ROWS(5) a získáme zase jiný plán
DBI026 -DB Aplikace - MFF UK Stejné, jako bez nápovědy Optimalizace v Oracle A opět spojení obou tabulek, minimalizujeme cenu nalezení prvních 5 řádek bez použití indexu EMP_DEPTNO_INX SQL> SELECT 2 /*+ FIRST_ROWS(5) NO_INDEX(Emp Emp_Deptno_Inx)*/ 3 Emp.*, Dept.Loc 4 FROM Emp, Dept 5 WHERE Dept.DeptNo=Emp.DeptNo; Execution Plan SELECT STATEMENT Optimizer=CHOOSE (Cost=5 Card=14 Bytes=574) 1 0 HASH JOIN (Cost=5 Card=14 Bytes=574) 2 1 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=14 Bytes=448) 3 1 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=4 Bytes=36) Statistics recursive calls 0 db block gets 15 consistent gets 0 physical reads 0 redo size 1352 bytes sent via SQL*Net to client 495 bytes received via SQL*Net from … 4 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 14 rows processed
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Jak se spočtou řádky? SQL> SELECT COUNT(*) 2 FROM Dept; Execution Plan SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1) 1 0 SORT (AGGREGATE) 2 1 INDEX (FULL SCAN) OF 'DEPT_PK' (UNIQUE) (Cost=1 Card=4) Statistics recursive calls 0 db block gets 1 consistent gets 0 physical reads 0 redo size 303 bytes sent via SQL*Net to client 495 bytes received via SQL*Net from … 4 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed Spočtou se záznamy v indexu přes primární klíč
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Jak se spočtou řádky? Index Dept_PK zakážeme. SQL> SELECT 2 /*+ NO_INDEX(Dept Dept_PK)*/ 3 COUNT(*) 4 FROM Dept; Execution Plan SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1) 1 0 SORT (AGGREGATE) 2 1 BITMAP CONVERSION (COUNT) 3 2 BITMAP INDEX (FAST FULL SCAN) OF 'DEPT_LOC_INX' Statistics recursive calls 0 db block gets 3 consistent gets 0 physical reads 0 redo size 303 bytes sent via SQL*Net to client 495 bytes received via SQL*Net from … 4 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed Spočtou se bity v bitmapovém indexu. Pro více řádek by tato metoda měla přednost, protože je objem indexu menší
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Jak se spočtou řádky? Indexy zcela zakážeme. SQL> SELECT 2 /*+ NO_INDEX (Dept)*/ 3 COUNT(*) 4 FROM Dept; Execution Plan SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1) 1 0 SORT (AGGREGATE) 2 1 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=4) Statistics recursive calls 0 db block gets 7 consistent gets 0 physical reads 0 redo size 303 bytes sent via SQL*Net to client 495 bytes received via SQL*Net from … 4 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed Spočtou se řádky tabulky. Počet přístupů k datům (consistent gets) postupně rostl 1, 3, 7
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Příkaz EXPLAIN PLAN. SQL> EXPLAIN PLAN 2 SET STATEMENT_ID='pokus' 3 FOR 4 SELECT --+ RULE 5 Emp.*, Dept.Loc 6 FROM Dept, Emp 7 WHERE Dept.DeptNo=Emp.DeptNo; Kroky plánu se uloží do tabulky PLAN_TABLE.
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Výběr dat z PLAN_TABLE bez struktury. SQL> SELECT Statement_ID, ID, Parent_ID, Optimizer, Operation 2 FROM Plan_Table 3 where Statement_ID='pokus'; STATEMENT_ID ID PARENT_ID OPTIMIZER OPERATION pokus 0 HINT: RULE SELECT STATEMENT pokus 1 0 NESTED LOOPS pokus 2 1 TABLE ACCESS pokus 3 1 ANALYZED TABLE ACCESS pokus 4 3 ANALYZED INDEX
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Výběr dat z PLAN_TABLE se strukturou. SQL> SELECT Lpad(' ',2*Level-2)||Operation||' '||Options ||' '||Object_Name Text 2 FROM Plan_Table 3 CONNECT BY PRIOR Statement_ID = Statement_ID 4 AND PRIOR ID = Parent_ID 5 START WITH Statement_ID='pokus' 6 AND ID = 0; TEXT SELECT STATEMENT NESTED LOOPS TABLE ACCESS FULL EMP TABLE ACCESS BY INDEX ROWID DEPT INDEX UNIQUE SCAN DEPT_PK
DBI026 -DB Aplikace - MFF UK Optimalizace v Oracle Zrušíme statistiky na tabulkách, optimalizátor v režimu CHOOSE bude používat Rule-Based optimalizaci –ANALYZE TABLE Emp COMPUTE STATISTICS; –ANALYZE TABLE Dept COMPUTE STATISTICS;
DBI026 -DB Aplikace - MFF UK Clustery Speciální organizace tabulek –Více tabulek často spojovaných přes společný sloupec, nebo více sloupců, je možné uložit do tzv. clusteru. CREATE CLUSTER EmpDept(X NUMBER(3)); CREATE INDEX EmpDeptInx ON CLUSTER EmpDept; CREATE TABLE EMP(…) CLUSTER EmpDept(DeptNo); CREATE TABLE DEPT(…) CLUSTER EmpDept(DeptNo); Hodnoty sloupců clusteru jsou ukládány unikátně (úspora místa) Ostatní data řádek tabulek jsou ukládány blízko odpovídajících hodnot (úspora času při spojování) Větší režie při aktualizacích EmpDept EmpDept