Néhány speciális adatszerkezet (BITMAP, IOT, CLUSTER, PARTICIO, HISZTOGRAM) Bitmap index CREATE BITMAP INDEX pkod_bm ON szallit(pkod); CREATE BITMAP INDEX szkod_bm ON szallit(szkod); -- Példa bitmap index használatára select * from szallit where pkod=10 and szkod=12; ------------------------------------------------ SELECT STATEMENT TABLE ACCESS BY INDEX ROWID SZALLIT BITMAP CONVERSION TO ROWIDS BITMAP AND BITMAP INDEX SINGLE VALUE PKOD_BM BITMAP INDEX SINGLE VALUE SZKOD_BM Index szervezett tábla CREATE TABLE cikk_iot ( ckod integer, cnev varchar2(20), szin varchar2(15), suly float, CONSTRAINT cikk_iot_pk PRIMARY KEY (ckod) ) ORGANIZATION INDEX PCTTHRESHOLD 20 INCLUDING cnev OVERFLOW TABLESPACE system; select * from cikk_iot where szin='piros'; ----------------------------------------- SELECT STATEMENT INDEX FAST FULL SCAN CIKK_IOT_PK select * from cikk_iot where ckod between 10 and 20; --------------------------------------------------- SELECT STATEMENT INDEX RANGE SCAN CIKK_IOT_PK -- Index clusteren levő táblák select * from emp_clt e natural join dept_clt d where deptno=10; ---------------------------------------------------------------- SELECT STATEMENT + + MERGE JOIN + CARTESIAN + TABLE ACCESS + CLUSTER + DEPT_CLT INDEX + UNIQUE SCAN + PERSONNEL_CL_IDX BUFFER + SORT + TABLE ACCESS + CLUSTER + EMP_CLT -- Hash clusteren levő táblák select cnev, suly from cikk_hclt where ckod=1; ---------------------------------------------- SELECT STATEMENT + + TABLE ACCESS + HASH + CIKK_HCLT select * from cikk_hclt natural join szallit_hclt where ckod=1; --------------------------------------------------------------- SELECT STATEMENT + + MERGE JOIN + CARTESIAN + TABLE ACCESS + HASH + CIKK_HCLT BUFFER + SORT + TABLE ACCESS + HASH + SZALLIT_HCLT -- Particionált tábla és index CREATE TABLE szallit_part ( szkod integer, ckod integer, pkod integer, mennyiseg integer, datum date) PARTITION BY RANGE ( ckod ) (PARTITION sz1 VALUES LESS THAN ( 200 ), PARTITION sz2 VALUES LESS THAN ( 500 ), PARTITION sz3 VALUES LESS THAN ( 800 ), PARTITION sz4 VALUES LESS THAN ( MAXVALUE) ); -- Az alábbi lekérdezésben csak egy partíciót olvas a rendszer. (lásd még -> PARTITION_START, PARTITION_STOP oszlopok) select sum(mennyiseg) from szallit_part where ckod=1; ---------------------------------------------------- SELECT STATEMENT SORT AGGREGATE PARTITION RANGE SINGLE TABLE ACCESS FULL SZALLIT_PART -- Itt viszont látható módon az összes partíciót olvassa. select sum(mennyiseg) from szallit_part where ckod+1=2; ------------------------------------------------------ SELECT STATEMENT SORT AGGREGATE PARTITION RANGE ALL TABLE ACCESS FULL SZALLIT_PART -- Partícionált lokális index (prefixelt) CREATE INDEX loc_i ON szallit_part(ckod) LOCAL (PARTITION sz1_i, PARTITION sz2_i, PARTITION sz3_i, PARTITION sz4_i); -- Partícionált lokális index (nem prefixelt) CREATE INDEX loc_i2 ON szallit_part(datum) LOCAL (PARTITION sz1_i2, PARTITION sz2_i2, PARTITION sz3_i2, PARTITION sz4_i2); select sum(mennyiseg) from szallit_part where ckod=1; ---------------------------------------------------- SELECT STATEMENT SORT AGGREGATE TABLE ACCESS BY LOCAL INDEX ROWID SZALLIT_PART INDEX RANGE SCAN LOC_I select sum(mennyiseg) from szallit_part where ckod=1 or ckod=601; ---------------------------------------------------------------- SELECT STATEMENT SORT AGGREGATE INLIST ITERATOR PARTITION RANGE ITERATOR TABLE ACCESS BY LOCAL INDEX ROWID SZALLIT_PART INDEX RANGE SCAN LOC_I -- Az alábbi lekérdezés a partícionált index összes partícióját olvassa, mivel elvileg -- bármelyik partícióban előfordulhat az adott dátum. -- (Írjuk át a dátumot 2003-05-01-re, és ekkor nem fog indexet használni. Vajon miért? -> lásd előfordulások száma) SELECT SUM(mennyiseg) FROM SZALLIT_PART WHERE datum=TO_DATE('2003-12-01', 'yyyy-mm-dd'); --------------------------------------------------------------------------------------- SELECT STATEMENT SORT AGGREGATE PARTITION RANGE ALL TABLE ACCESS BY LOCAL INDEX ROWID SZALLIT_PART INDEX RANGE SCAN LOC_I2 -- Partícionált globális index (prefixelt) -- Az oszlopsorrend forditva nem lehet, mert akkor nem lenne prefixelt -- Az indexet létre lehetne úgy is hozni, de az nem lehetne partícionált index CREATE INDEX glob_i ON szallit_part(pkod, szkod) GLOBAL PARTITION BY RANGE (pkod) (PARTITION pkod_1 VALUES LESS THAN (10), PARTITION pkod_2 VALUES LESS THAN (MAXVALUE)); -- Az alábbi lekérdezés a partícionált indexnek csak egyetlen partícióját használja. select sum(mennyiseg) from szallit_part where pkod=1; ---------------------------------------------------- SELECT STATEMENT SORT AGGREGATE PARTITION RANGE SINGLE TABLE ACCESS BY GLOBAL INDEX ROWID SZALLIT_PART INDEX RANGE SCAN GLOB_I -- Az alábbi lekérdezés a dátum szerinti partícionált index összes partícióját használja, -- a ckod szerintinek viszont csak néhány partícióját. SELECT SUM(mennyiseg) FROM SZALLIT_PART WHERE datum=SYSDATE OR (ckod=1 OR ckod=601); ----------------------------------------------------------------------------------- SELECT STATEMENT SORT AGGREGATE CONCATENATION INLIST ITERATOR PARTITION RANGE ITERATOR TABLE ACCESS BY LOCAL INDEX ROWID SZALLIT_PART INDEX RANGE SCAN LOC_I PARTITION RANGE ALL TABLE ACCESS BY LOCAL INDEX ROWID SZALLIT_PART INDEX RANGE SCAN LOC_I2 -- Statisztikák létrehozása -- Feltölti a user_tables, user_tab_columns (vagy user_tab_col_statistics) és user_histograms táblákat analyze table szallit compute statistics; -- Hisztogram intervallumainak számát így adjuk meg analyze table szallit compute statistics for columns ckod size 15; -- Statisztikák törlése analyze table szallit delete statistics; -- A statisztikák létrehozására, törlésére, lock-olására és egyéb műveletek -- elvégzésére használhatjuk a DBMS_STATS package alprogramjait is. -- Sőt ma már ez az ajánlott módszer az ANALYZE helyett, ami már csak a kompatibilitás miatt van meg. CALL dbms_stats.gather_table_stats('nikovits','szallit'); CALL dbms_stats.delete_table_stats('nikovits','szallit'); CALL dbms_stats.delete_column_stats('nikovits','szallit', 'ckod'); BEGIN dbms_stats.gather_table_stats('NIKOVITS', 'SZALLIT', method_opt => 'FOR COLUMNS mennyiseg SIZE 15' ); END; -- Statisztikák lekérdezése SELECT table_name, num_rows FROM user_tables WHERE table_name='SZALLIT'; -- A density oszlop a szelektivitásra utal, a histogram pedig annak típusára. -- (FREQUENCY, HEIGHT BALANCED, HYBRID) SELECT table_name, column_name, num_distinct, low_value, high_value, num_nulls, density, num_buckets, histogram FROM user_tab_columns WHERE table_name='SZALLIT'; (A user_tab_col_statistics kevesebb oszlopot tartalmaz, mint az előző, de a fenti oszlopok abban is megvannak) -- Hisztogram-beli intervallumok lekérdezése SELECT table_name, column_name, endpoint_value, endpoint_number FROM user_histograms WHERE table_name = 'SZALLIT' AND column_name='MENNYISEG' ORDER BY endpoint_value; A hisztogram a tábla egy adott oszlopában szereplő értékek eloszlásáról ad információt. Ez tulajdonképpen egy oszlopdiagramnak felel meg, ahol az oszlop magassága az adott intervallumba esés gyakoriságát adja meg, vagyis azt, hogy a táblának hány olyan sora van, amelyben a táblabeli oszlop értéke az adott hisztogrambeli intervallumba esik. A hisztogram intervallumainak végpontjait az ENDPOINT_VALUE adja meg, a gyakoriságokat pedig az ENDPOINT_NUMBER, de ez utóbbi kumulatív módon. Vagyis egy endpoint_number azt adja meg, hogy hány olyan sora van a táblának, amelyben az értékek ebbe, illetve a megelőző intervallumokba esnek. Példa: endpoint_value endpoint_number -------------------------------- 1 537 9 1232 17 1995 ... A fenti hisztogram azt mutatja, hogy a táblának 537 sorában az érték <= 1, 1232 sorában az érték <= 9, 1995 sorában az érték <= 17, stb. SELECT COUNT(*) FROM nikovits.szallit WHERE mennyiseg<=1; SELECT COUNT(*) FROM nikovits.szallit WHERE mennyiseg<=9; SELECT COUNT(*) FROM nikovits.szallit WHERE mennyiseg<=17;