You are on page 1of 26

T i u cu l nh Oracle SQL ph n 1: n n t ng c b n

Ti u cu lnh l ch nng cao, v vy c th hiu c cc k thut ti u cu lnh Oracle SQL, chng ta cn tm hiu mt s khi nim c bn lin quan n lnh vc ny, bi vit ny khng nhm mc ch chuyn ti ton b kin thc lin quan n ti u cu lnh SQL, bi vit ch trnh by nhng khi nim quan trng nht, gip nhng c gi am hiu kin trc Oracle c th hiu c.

N n t ng c b n
Trnh t x l cu l nh SQL
Oracle Server x l cu lnh SQL theo trnh t cc bc sau:

1. Open 2. Parse
o o o o o o o o o

Ngm nh khai bo v khi to Cursor cho cu lnh SQL Kim tra cu lnh thc hin trc cha, nu c th chuyn sang thc hin bc 3 Phn tch v kim tra c php cu lnh SQL Kim tra tnh hp l v quyn truy cp n cc i tng d liu cu lnh tham chiu ti Xc nh s thc thi cu lnh SQL ti u nht Tm v gn gi tr cho cc bind-variable nu c Thc thi cc bc m t trong s thc thi cu lnh SQL Chuyn kt qu v ni gi thc thi lnh Ngm nh ng Cursor cho cu lnh

3. Bind

4. Execute 5. Fetch 6. Close

Trong cc giai on x l trn, giai on Parse chim nhiu thi gian nht.

Cng c t i u cu l nh SQL*Plus AUTOTRACE


Ch c nng

Thu thp thng tin m t qu trnh thc thi cu lnh SQL, thng c dng ti u cu lnh. Ci t s dng y chc nng ca cng c ny, cn to Table tn PLAN_TABLE v gn nhm quyn PLUSTRACE cho ti khon mun s dng cng c:

1. Dng $ORACLE_HOME/rdbms/admin/utlxplan.sql to PLAN_TABLE


2.

Dng ti khon DBA chy m lnh $ORACLE_HOME/sqlplus/admin/plustrce.sql to nhm quyn PLUSTRACE.

V d

Quan st kt qu t m dn trn, ta thy cng c AUTOTRACE gi v ba nhm thng tin sau: 1. 2. 3. Kt qu cu lnh S trnh t thc thi cu lnh Thng tin thng k chi ph ti nguyn cn dng thc thi cu lnh

Cch s d ng

C php l nh SET AUTOTRACE ON SET AUTOTRACE OFF SET AUTOTRACE ON EXPLAIN SET AUTOTRACE ON STATISTICS SET AUTOTRACE TRACEONLY SET AUTOTRACE TRACEONLY EXPLAIN SET AUTOTRACE TRACEONLY STATISTICS

ngha Bt tnh nng thu thp v hin th thng tin y Tt tnh nng thu thp v hin th thng tin Hin th kt qu v EP cu lnh Hin th kt qu v thng tin thng k cu lnh Hin th EP v thng tin thng k, khng hin th kt qu cu lnh Ch hin th EP Ch hin th thng k

S th c thi cu l nh SQL
S thc thi cu lnh SQL (Execution Plan - EP) m t th t cc bc Oracle cn thc thi c c kt qu cu lnh nhanh nht. V d v EP ca cu lnh xem d liu trn hai Table CUSTOMERS v COUNTRIES:

Oracle qui nh th t x l cc bc ca EP nh sau: 1. 2. Bt u x l t bc nm tht v pha bn phi nht, tip theo l cc bc ng k trc n Nu hai bc c cng th t th s x l bc nm pha trn trc

Nh vy, ta thy EP trn c x l theo th t c nh s bn phi. Mt EP y bao gm ba thnh t sau: phng thc truy cp d liu, phng php JOIN v th t JOIN gia hai hay nhiu tp d liu.

Ph ng th c truy c p d li u

Xc nh cch thc truy cp vt l n tng dng d liu ca Table, v du mt s phng php truy cp d liu Table ph bin:

Truy cp theo cch c tng dng ca Table ( TABLE ACCESS (FULL) ): c ton b dng d liu ca Table i snh d liu, v vy nu Table c kch thc ln th phng thc truy cp ny s chim nhiu chi ph IO. Tuy nhin, cch truy cp ny cho php chng ta c th cu hnh c nhiu khi d liu (Block) cho mt thao tc c v nhiu tin trnh cng c mt lc.

Truy cp d liu cy Index (INDEX SCAN): duyt cy Index theo gi tr kha cn tm, kt qu tm c c lu gi tr ROWID ca dng d liu cha gi tr kha

Truy cp d liu Table theo Index ( TABLE ACCESS (BY INDEX ROWID)): phng thc truy cp ny bao gm hai bc tch bit:

1. 2.

Duyt cy Index tm ROWID tng ng vi gi tr kha c dng d liu ca Table theo ROWID tm c mt cch nhanh nht

Vi cch ny, ta thy c c mt dng d liu ca Table th phi tn t nht hai thao tc IO; mt thao tc IO c trn cy Index v mt thao tc IO c trn Table. Theo lut chung th cch ny thch hp khi kt qu d liu cn tm t hn 5% khi lng d liu ca Table.

Ph ng php JOIN
Xc nh phng php kt hp d liu gia hai hay nhiu Table vi nhau, v d v phng php JOIN gia hai Table T1 v T2:

1. NESTED LOOP JOIN: vi T1 l outer-table, T2 l inner-table th tng dng d liu ca Table T1 s kt hp so


2. snh vi tt c dng d liu ca Table T2, kt qu tr v l tt c cc dng d liu tha iu kin so snh. SORT MERGE JOIN: tp dng d liu ca hai Table c sp theo th t trc khi ng dng thut ton trn trn chng.

Th t JOIN
Xc nh th t JOIN khi cu lnh SQL c nhiu hn hai Table kt hp vi nhau, th t JOIN hp l gip gim thiu d liu cn kt hp vi nhau m vn t c kt qu ng. Sau khi tm hiu qua cc khi nim c bn, chng ta th quay li tm hiu ngha EP ca cu lnh SQL trn: 1. 2. 3. 4. Oracle chn phng php JOIN l NESTED LOOP thc hin php JOIN gia hai Table. Oracle chn CUSTOMERS ng vai tr l outer-table, COUNTRIES l inner-table Bt u c tng dng d liu ca CUSTOMERS ri so trng vi tt c dng ca COUNTRIES, im lu l gi tr COUNTRIES.COUNTRY_ID ny c ly t cy Index COUNTRY_PK Kt qu tr v l tt c nhng dng d liu tha iu kin so trng

n y c th cc bn thc mc l ti sao Oracle li chn phng php Join l NESTED LOOP ? ti sao CUSTOMERS li c chn lm outer-table ?, quyt nh chn ny c thc hin bi Trnh ti u cu lnh Oracle.

Trnh t i u cu l nh Oracle
Trnh ti u gip Oracle xc nh c mt EP tt nht cho mt cu lnh SQL. Trnh ti u Oracle 9i h tr phng php ti u da vo c php lnh (Rule Based Optimizer RBO) v phng php ti u da vo chi ph c tnh cn dng thc thi cu lnh (Cost Based Optimizer CBO). Mc nh Oracle9i dng RBO.

RBO
RBO c t phin bn Oracle6, da vo cu trc cu lnh SQL xc nh EP tt nht. RBO s dng mt lc phn hng cc phng thc truy cp d liu chn phng thc truy cp cho EP, phng thc no c s hng thp s c u tin chn. Lc phn hng cc phng thc truy cp d liu c qui nh nh sau:

Ta thy truy cp theo ROWID c s hng thp nht l 1; ngha l phng thc truy cp n d liu nhanh nht, v truy cp theo Index c s hng l 4 s nhanh hn nhiu so vi truy cp theo Full-Table-Scan c s hng cao nht l 15. V d sau cho thy RBO s dng lut phn hng chn phng thc truy cp d liu cho EP. Do ct CUST_ID ca iu kin WHERE c UNIQUE INDEX ln RBO chn phng thc truy cp theo Index: SQL> DROP TABLE new_table;

Table dropped.

SQL> CREATE TABLE new_table AS SELECT object_id, object_name, object_type FROM all_objects WHERE rownum <= 5000; 2 3 4

Table created. SQL> SET AUTOTRACE TRACEONLY EXPLAIN SQL> SELECT * FROM new_table WHERE object_type = 'TABLE'; Execution Plan ---------------------------------------------------------0 1 SELECT STATEMENT Optimizer=CHOOSE 0 TABLE ACCESS (FULL) OF 'NEW_TABLE'

SQL> SET AUTOTRACE OFF SQL> CREATE INDEX idx_object_type ON new_table(object_type);

Index created. SQL> SET AUTOTRACE TRACEONLY EXPLAIN SQL> SELECT * FROM new_table WHERE object_type = 'TABLE'; Execution Plan ---------------------------------------------------------0 1 2 SELECT STATEMENT Optimizer=CHOOSE 0 TABLE ACCESS (BY INDEX ROWID) OF 'NEW_TABLE' 1 INDEX (RANGE SCAN) OF 'IDX_OBJECT_TYPE' (NON-UNIQUE)

CBO
CBO c t phin bn Oracle7, CBO da vo thng tin tng hp c c tnh chi ph ca EP, EP tt nht l EP c chi ph c tnh nh nht. Oracle9i ch dng CBO ti u nu i tng tham chiu n c thng tin m t. Thng tin tng hp trong ng cnh ny bao gm: 1. 2. 3. Thng tin v h iu hnh my ch Oracle: s CPU, tc c ghi a cng, kch thc khi d liu, c ch qun l a Thng tin m t cc i tng d liu: s dng, ct v khi d liu ca Table, kch thc dng, chiu cao v s nt l ca cy Index Thng tin v cc thng s lin quan: optimizer_mode, db_file_multiblock_read_count, parallel_automatic_tuning

Nu cung cp y v chnh xc cc thng tin trn, trnh ti u CBO c th xc nh c mt EP tt nht. Tip theo v d trong phn RBO, chng ta dng lnh ANALYZE TABLE thu thp thng tin ca NEW_TABLE cho trnh ti u: SQL> SET AUTOTRACE OFF SQL> @li NEW_TABLE

indexes on table NEW_TABLE%:

TABLE_NAME

INDEX_TYPE INDEX_NAME

-------------------- ---------- -----------------------------NEW_TABLE NONUNIQUE IDX_OBJECT_TYPE

SQL> ANALYZE TABLE new_table COMPUTE STATISTICS;

Table analyzed.

SQL> SET AUTOTRACE TRACEONLY EXPLAIN SQL>SELECT * FROM new_table WHERE object_type = 'TABLE';

Execution Plan ---------------------------------------------------------0 1 SELECT STATEMENT Optimizer=CHOOSE (Cost=5 Card=2500 Bytes=107500) 0 TABLE ACCESS (FULL) OF 'NEW_TABLE' (Cost=5 Card=2500 Bytes=107500)

Ta thy kt qu ca EP c mt s im khc bit so vi thi im trc khi thu thp thng tin: 1. 2. C thm thng tin v chi ph thc hin ca mi bc lnh: (Cost=5 Card=2500 Bytes=107500), iu ny chng t Oracle hin ang dng trnh ti u CBO CBO chn phng thc truy cp TABLE ACCESS (FULL) mc d c tn ti Index trn ct object_type.

Ph l c
Gi i ngha t
Bind-variable: k thut vit m khng gn gi tr c nh, k thut ny gip tng tnh sn sng, hiu nng v bo mt cho h thng Oracle. V d: M khng dng Bind-Variable BEGIN UPDATE employees SET SALARY=SALARY + 100 WHERE employee_id = 100; END; M dng Bind-Variable DECLARE bind_var NUMBER := 100; BEGIN UPDATE employees SET SALARY=SALARY + 100 WHERE employee_id = bind_var; END; Outer-table: tng dng d liu ca Table ny s i snh vi tt c dng ca inner-table, cn gi l driving-table, c cp n trong phng php NESTED LOOP JOIN, thng i chung vi thut ng inner-table Inner-table: tt c dng d liu ca Table ny s c i snh vi tng dng ca outer-table.

M l nh
Mt s File m lnh tin ch s dng trong bi vit: Tn m l nh M t ch c nng Lit k tt c Index ca bng nhp vo select ui.table_name , decode(ui.index_type ,'NORMAL', ui.uniqueness li.sql , from where ,ui.index_type) as index_type ui.index_name user_indexes ui ui.table_name like upper('&1.%')

order by ui.table_name
, ui.uniqueness desc

L ch s thay i
1. 2. 10/02/2009 - Gii thiu bi vit 20/02/2009 - B sung phn "Cng c ti u cu lnh: SQL*Plus AUTOTRACE

Tham kh o

1. Cch s dng "Bind Variable" khi lp trnh Java vi Oracle 2. Ti liu chun ca Oracle Database 9i 3. Ti liu kha hc Oracle Database 9i: SQL Tuning

Mi cc bn c phn tip theo ca ch ny:

Ph n 2 T i u cu l nh SQL c Table v c m t i u ki n

Ph n 2: T i u cu l nh SQL c m t Table v c m t i u ki n
Tip theo Phn 1: nn tng c bn ti u cu lnh Oracle SQL; gii thiu cc kin thc c bn cn thit ti u cu lnh SQL, chng ta bt u i vo tm hiu k thut ti u cu lnh c bn nht, l ti u da vo Index, c th l B*tree-Index, loi Index thng c dng nht. Chng ta cng cn lu l Index ch gip tng tc truy vn trong mt s trng hp c th, khng phi bt k trng hp no s dng Index cng gip tng tc . Trong thc t, ta c th xem phn mc lc ca mt cun sch ging nh mt cu trc Index; t mc lc cun sch, bn suy ra c s th t trang sch cha ni dung bn cn tm. Nu sch vi trm trang bn c th da vo mc lc tm c ni dung mong mun mt cch nhanh chng, nhng nu sch ch vi trang th tm theo cch lt tng trang th li nhanh hn. Cch tm theo mc lc ging nh phng thc truy cp TABLE ACCESS (BY INDEX ROWID), cch tm lt tng trang sch ging nh phng thc truy cp TABLE ACCESS (FULL). Phn hai ny s tp trung ch yu vo k thut ti u cu lnh s dng Index, xem xt trng hp no Oracle s dng Index trong cu lnh v ngc li. Cc v d minh ha trong bi s dng Table tn CUSTOMERS ca ti khon SH, cu trc CUSTOMERS nh sau: [oracle@localhost LABS]$ sid ORACLE_SID=ora9i [oracle@localhost LABS]$ [oracle@localhost LABS]$ alias sh alias sh='sqlplus "sh/sh"' [oracle@localhost LABS]$ sh

SQL*Plus: Release 9.2.0.4.0 - Production on Mon Feb 16 08:56:20 2009

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

Connected to: Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production With the Partitioning and Oracle Data Mining options JServer Release 9.2.0.4.0 - Production

SQL> DESC customers Name Null? Type

----------------------------------------------------------- -------- --------------CUST_ID CUST_FIRST_NAME CUST_LAST_NAME CUST_GENDER CUST_YEAR_OF_BIRTH CUST_MARITAL_STATUS CUST_STREET_ADDRESS CUST_POSTAL_CODE CUST_CITY CUST_STATE_PROVINCE COUNTRY_ID CUST_MAIN_PHONE_NUMBER CUST_INCOME_LEVEL CUST_CREDIT_LIMIT CUST_EMAIL CUST_TOTAL NOT NULL NUMBER NOT NULL VARCHAR2(20) NOT NULL VARCHAR2(40) CHAR(1) NUMBER(4) VARCHAR2(20) NOT NULL VARCHAR2(40) NOT NULL VARCHAR2(10) NOT NULL VARCHAR2(30) VARCHAR2(40) NOT NULL CHAR(2) VARCHAR2(25) VARCHAR2(30) NUMBER VARCHAR2(30) VARCHAR2(14)

SQL>

Cc tr ng h p ng d ng Index khi t i u cu l nh SQL


Oracle khng dng Index cho i u ki n so snh c ton t < >, != v NOT IN

Thng chng ta ngh nu ct d liu trong mnh iu kin c Index, th cu lnh SQL s s dng Index truy vn d liu cho nhanh, tuy nhin c nhiu trng hp d c Index nhng Index vn khng c. Trng hp u tin chng ta xt n l i vi cc ton t <>, != v NOT IN. Trc tin, ta kim tra Table tn CUSTOMERS hin ang c nhng Index no: SQL> @li CUSTOMERS

indexes on table CUSTOMERS%:

TABLE_NAME

INDEX_TYPE INDEX_NAME

-------------------- ---------- -----------------------------CUSTOMERS UNIQUE CUSTOMERS_PK

NONUNIQUE CUST_CREDIT_LIMIT_IDX CUST_EMAIL_IDX CUST_LAST_NAME_IDX Dng m lnh dai.sql xa cc nonprimary-key, khi CUSTOMERS ch cn primary-key tn CUSTOMERS_PK trn ct d liu CUST_ID: SQL> @dai on which table: CUSTOMERS DROP INDEX CUSTOMERS_PK * ERROR at line 1: ORA-02429: cannot drop index used for enforcement of unique/primary key

SQL> @li CUSTOMERS

indexes on table CUSTOMERS%:

TABLE_NAME

INDEX_TYPE INDEX_NAME

-------------------- ---------- -----------------------------CUSTOMERS UNIQUE CUSTOMERS_PK

Xem cch trnh ti u Oracle x l bn cu lnh sau: SQL> SET AUTOTRACE TRACEONLY EXPLAIN

SQL> SELECT cust_first_name, cust_last_name FROM customers WHERE cust_id = 1030 /

Execution Plan ---------------------------------------------------------0 1 2 SELECT STATEMENT Optimizer=CHOOSE 0 TABLE ACCESS (BY INDEX ROWID) OF 'CUSTOMERS' 1 INDEX (UNIQUE SCAN) OF 'CUSTOMERS_PK' (UNIQUE)

SQL> SELECT cust_first_name, cust_last_name FROM customers

WHERE cust_id < 20000 /

Execution Plan ----------------------------------------------------------

0 1 2

SELECT STATEMENT Optimizer=CHOOSE 0 TABLE ACCESS (BY INDEX ROWID) OF 'CUSTOMERS' 1 INDEX (RANGE SCAN) OF 'CUSTOMERS_PK' (UNIQUE)

SQL> SELECT cust_first_name, cust_last_name FROM customers

WHERE cust_id between 70000 and 80000 /

Execution Plan ---------------------------------------------------------0 1 2 SELECT STATEMENT Optimizer=CHOOSE 0 TABLE ACCESS (BY INDEX ROWID) OF 'CUSTOMERS' 1 INDEX (RANGE SCAN) OF 'CUSTOMERS_PK' (UNIQUE)

SQL> SELECT cust_first_name, cust_last_name FROM customers

WHERE cust_id <> 1030 /

Execution Plan ---------------------------------------------------------0 SELECT STATEMENT Optimizer=CHOOSE

0 TABLE ACCESS (FULL) OF 'CUSTOMERS'

SQL> Nhn vo kt qu cc cu lnh, ta thy trnh ti u Oracle ang c ch nh gi tr l Optimizer=CHOOSE, ngha l s chn CBO nu CUSTOMERS c thng tin m t v chn RBO nu khng c. Mc nh CUSTOMERS khng c thng tin m t, v vy trong trng hp ny trnh ti u s dng phng php RBO xc nh EP cho cc cu lnh. Nh tm hiu trong phn trc, RBO s dng lc lut phn hng chn EP tt nht, u tin chn phng thc truy cp d liu theo Index hn l phng thc duyt tng dng d liu ca Table. Nhng theo v d trn, ta thy RBO ch dng Index cho 3 cu lnh u tin, khng dng Index cho cu lnh cui cng. th ta thy ba cu lnh u s dng ton t so snh =, < v BETWEEN AND, cc ton t ny u c khuynh hng gii hn tp d liu tr v, cn cu lnh th t th s dng ton t <>, ton t ny lun tr v tp kt qu ln. Nh vy, Oracle RBO ng x nh vy l hp l, dng Index cho cu lnh s dng ton t so snh c khuynh hng tr v t d liu v khng dng Index cho trng hp cu lnh c ton t so snh tr v nhiu d liu. RBO s ng x tng t nh <> cho cc ton t != v NOT IN.

Oracle khng dng Index cho c t d li u k t h p v i b t k thnh ph n khc


D ct d liu c Index, nhng nu ta kt hp n vi bt k thnh phn no khc, chng hn nh mt gi tr, mt biu thc th Index trn ct d liu s khng c trnh ti u Oracle ng dng. Xem xt cc v d di y: SQL> SELECT * 2 FROM customers 3 WHERE cust_id + 1 = 100;

Execution Plan ---------------------------------------------------------0 1 SELECT STATEMENT Optimizer=CHOOSE 0 TABLE ACCESS (FULL) OF 'CUSTOMERS'

SQL> SELECT * 2 FROM customers 3 WHERE TO_NUMBER(cust_id) = 100;

Execution Plan ---------------------------------------------------------0 1 SELECT STATEMENT Optimizer=CHOOSE 0 TABLE ACCESS (FULL) OF 'CUSTOMERS'

SQL> SELECT * 2 FROM customers 3 WHERE cust_id + null = 100;

Execution Plan ---------------------------------------------------------0 1 SELECT STATEMENT Optimizer=CHOOSE 0 TABLE ACCESS (FULL) OF 'CUSTOMERS'

SQL> SELECT * 2 FROM customers 3 WHERE cust_id = 100;

Execution Plan ---------------------------------------------------------0 1 SELECT STATEMENT Optimizer=CHOOSE 0 TABLE ACCESS (BY INDEX ROWID) OF 'CUSTOMERS'

INDEX (UNIQUE SCAN) OF 'CUSTOMERS_PK' (UNIQUE)

SQL> Ta thy ba trng hp u tin, d ct d liu kt hp vi gi tr NULL , gi tr rng, cng khin Oracle RBO khng ng dng Index cho cu lnh. i vi trng hp TO_NUMBER(cust_id) th do hm TO_NUMBER kt buc vi ct CUST_ID nn lm mt tc dng ca Index, tuy nhin chng ta c th s dng k thut function-based Index; to Index trc tip trn hm kt buc vo ct d liu, thc hin phng thc truy cp d liu theo Index m khng cn b hm TO_NUMBER().

SQL> CREATE INDEX cust_id_tonumber_idx ON customers(to_number(cust_id));

Index created.

SQL> @li

indexes on table CUSTOMERS%:

TABLE_NAME

INDEX_TYPE INDEX_NAME

-------------------- ---------- -----------------------------CUSTOMERS UNIQUE CUSTOMERS_PK

NONUNIQUE CUST_CREDIT_LIMIT_IDX FUNCTION-B CUST_ID_TONUMBER_IDX ASED NORMA L

SQL> SET AUTOTRACE TRACEONLY EXPLAIN

SQL> SELECT * 2 FROM customers 3 WHERE to_number(cust_id) = 100;

Execution Plan ---------------------------------------------------------0 1 SELECT STATEMENT Optimizer=CHOOSE 0 TABLE ACCESS (FULL) OF 'CUSTOMERS'

SQL> ANALYZE TABLE customers COMPUTE STATISTICS;

Table analyzed.

SQL> SELECT * 2 FROM customers 3 WHERE to_number(cust_id) = 100;

Execution Plan ---------------------------------------------------------0 1 2 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=137) 0 TABLE ACCESS (BY INDEX ROWID) OF 'CUSTOMERS' (Cost=2 Card=1 Bytes=137) 1 INDEX (RANGE SCAN) OF 'CUST_ID_TONUMBER_IDX' (NON-UNIQUE) (Cost=1 Card=1)

SQL> Nh ta thy, ch trnh ti u CBO mi hiu k thut Function-based Index, RBO khng hiu. V vy, trnh ti u Oracle t ng dng CBO th chng ta cn thu thp thng tin m t cho CUSTOMERS. Lu thm v cch thu thp thng tin m t cho Table, chng ta s dng c php lnh ANALYZE TABLE v lnh ny n gin, d hiu v c php trong sng, p ng cho cc minh ha ca chng ta. Khi ng dng thu thp thng tin cho h thng Oracle thc t, cc bn nn dng gi lnh DBMS_STATS th hiu qu hn.

Oracle Index v ton t LIKE


minh ha cho ny, chng ta s to thm mt Index trn ct d liu CUST_LAST_NAME theo m lnh ci.sql: SQL> @ci on which table : CUSTOMERS

on which column(s): cust_last_name

Creating index on: CUSTOMERS cust_last_name Enter value for index_name: cust_last_name_idx

SQL> @li CUSTOMERS

indexes on table CUSTOMERS%:

TABLE_NAME

INDEX_TYPE INDEX_NAME

-------------------- ---------- -----------------------------CUSTOMERS UNIQUE CUSTOMERS_PK

NONUNIQUE CUST_CREDIT_LIMIT_IDX FUNCTION-B CUST_ID_TONUMBER_IDX ASED NORMA L

NONUNIQUE CUST_LAST_NAME_IDX Tip theo, chng ta xt v d sau: SQL> SET AUTOTRACE TRACEONLY EXPLAIN

SQL> SELECT cust_id 2 FROM customers 3 WHERE cust_last_name LIKE 'S%' /

Execution Plan ---------------------------------------------------------0 1 2 SELECT STATEMENT Optimizer=CHOOSE 0 TABLE ACCESS (BY INDEX ROWID) OF 'CUSTOMERS' 1 INDEX (RANGE SCAN) OF 'CUST_LAST_NAME_IDX' (NON-UNIQUE)

SQL> SELECT cust_last_name 2 FROM customers 3 WHERE cust_last_name LIKE '%S% /

Execution Plan ---------------------------------------------------------0 1 SELECT STATEMENT Optimizer=CHOOSE 0 TABLE ACCESS (FULL) OF 'CUSTOMERS'

SQL> SELECT cust_id 2 FROM customers 3 WHERE cust_last_name LIKE '%S' /

Execution Plan ---------------------------------------------------------0 1 SELECT STATEMENT Optimizer=CHOOSE 0 TABLE ACCESS (FULL) OF 'CUSTOMERS'

SQL> Nh vy, trnh ti u Oracle RBO ch ng dng Index cho ton t LIKE nu gi tr so snh khng c k t c bit % u. Chng ta xt tip v d sau: SQL> SELECT cust_last_name 2 FROM customers 3 WHERE cust_last_name like 'S%' /

Execution Plan ---------------------------------------------------------0 1 SELECT STATEMENT Optimizer=CHOOSE 0 INDEX (RANGE SCAN) OF 'CUST_LAST_NAME_IDX' (NON-UNIQUE)

SQL>

Cc bn thy im khc bit y ch ? EP khng c bc lnh TABLE ACCESS (BY INDEX ROWID) nh bnh thng, m ch c INDEX (RANGE SCAN). Nguyn nhn do ct d liu kt qu tr v ch c CUST_LAST_NAME, m d liu ny chnh l gi tr kha ca Index tn CUST_LAST_NAME_IDX, v vy Oracle ch cn duyt cy Index l c th ly c kt qu mong mun, khng cn tn thm chi ph duyt Table nh bnh thng. Tip tc vi v d sau:

SQL> SELECT cust_last_name 2 FROM customers 3 WHERE cust_id LIKE '7%' /

Execution Plan ---------------------------------------------------------0 1 SELECT STATEMENT Optimizer=CHOOSE 0 TABLE ACCESS (FULL) OF 'CUSTOMERS'

SQL> Cc bn c on ra c l do ti sao trnh ti u Oracle RBO khng ng dng Index trn ct d liu CUST_ID ? Do CUST_ID l ct d liu kiu s, nhng cu lnh li so snh vi mt gi tr chui 7%, nn trong trng hp ny Oracle t ng ngm nh chuyn i kiu cho mnh iu kin thnh nh sau: SQL> SELECT cust_last_name 2 FROM customers 3 WHERE TO_CHAR(cust_id) LIKE '7%' Do ct d liu CUST_ID b kt buc vi hm TO_CHAR() khi so snh, nn b mt tc dng Index. Tm tt nhng chng ta tm hiu c trong phn ny:

1. Oracle ch ng dng Index cho ton t LIKE khi gi tr so snh khng c k t % u


2. 3.

Nu kt qu d liu ca cu lnh c th tm thy trong Index, th Oracle ch cn duyt cy Index ly kt qu tr v, m khng cn duyt trn Table. Nu ct d liu trong mnh iu kin so snh vi mt gi tr khc kiu, Oracle t ng chuyn i kiu ngm nh cho ct d liu , iu ny khin Index khng c ng dng.

Oracle Index v gi tr NULL


Theo kin trc c s d liu Oracle, cu trc cy Index ,B*tree-Index, khng lu thng tin v dng d liu ca Table c gi tr kha l NULL. Vy theo bn, Oracle s ng x th no khi so snh iu kin trn ct d liu c gi tr NULL ? chng ta s tm hiu ny ngay trong phn di y. chun b cho phn ny, chng ta cp nht mt s gi tr ca ct d liu CUST_EMAIL v NULL v to Index tn CUST_EMAIL_IDX trn ct ny. SQL> SET AUTOTRACE OFF

SQL> UPDATE customers 2 SET cust_email = null 3 WHERE rownum < 101 / 100 rows updated.

SQL> COMMIT;

Commit complete.

SQL> @ci on which table : CUSTOMERS

on which column(s): CUST_EMAIL

Creating index on: CUSTOMERS CUST_EMAIL Enter value for index_name: CUST_EMAIL_IDX

SQL> SET AUTOTRACE TRACEONLY EXPLAIN

SQL> SELECT cust_email 2 FROM customers 3 WHERE cust_email IS NULL /

Execution Plan ---------------------------------------------------------0 1 SELECT STATEMENT Optimizer=CHOOSE 0 TABLE ACCESS (FULL) OF 'CUSTOMERS'

SQL> Theo v d trn, Oracle khng dng Index d ct CUST_EMAIL c Index. Gii thch cho cch ng x ny l do B*tree-Index khng lu thng tin v dng d liu cha gi tr kha l NULL, v vy Oracle phi thc hin qut tng dng d liu ca Table tm c cc CUST_EMAIL c gi tr NULL. Vy cc bn th xem tip v d sau, ti sao Oracle vn khng dng Index ? SQL> SET AUTOTRACE TRACEONLY EXPLAIN

SQL> SELECT cust_id 2 FROM customers 3* WHERE cust_email IS NOT NULL SQL> /

Execution Plan ---------------------------------------------------------0 1 SELECT STATEMENT Optimizer=CHOOSE 0 TABLE ACCESS (FULL) OF 'CUSTOMERS'

SQL> Nu Oracle B*tree-Index khng lu gi tr NULL, vy khi tm gi tr khc NULL th theo suy lun bnh thng Oracle phi dng Index trong trng hp ny ? Khng nh vy, Oracle ngh rng iu kin IS NOT NULL s tr v tp kt qu ln, nu dng Index s khng hiu qu, nn Oracle chn phng thc truy cp d liu TABLE ACCESS (FULL) s hiu qu hn.

Ph l c
M l nh
Mt s File m lnh tin ch s dng trong bi vit: Tn m l nh M t ch c nng Lit k tt c Index ca bng nhp vo select ui.table_name , decode(ui.index_type ,'NORMAL', ui.uniqueness ,ui.index_type) as index_type , ui.index_name from user_indexes ui where ui.table_name like upper('&1.%') order by ui.table_name , ui.uniqueness desc

li.sql

Xa ht tt c non-primary key Index trn mt ct d liu nhp vo ca mt Table accept TABLE_NAME prompt " on which table: " set termout off store set saved_settings replace set heading off verify off autotrace off feedback off spool doit.sql select 'DROP INDEX '||ui.index_name||';' from user_indexes ui where table_name like upper('&TABLE_NAME.%') / spool off set termout on @doit @saved_settings undef TABLE_NAME set termout on

dai.sql

ci.sql To mi mt Non-Unique Index trn mt ct d liu nhp vo ca mt Table accept TABLE_NAME prompt " on which table :"

|accept COLUMN_NAME prompt " set store set set

on which column(s): "

termout off set saved_settings replace heading off feedback off autotrace off verify off termout on

select 'Creating index on: ' , '&&TABLE_NAME' , '&&COLUMN_NAME' FROM DUAL / create index &INDEX_NAME on &TABLE_NAME(&COLUMN_NAME) / @saved_settings set termout on undef INDEX_NAME undef TABLE_NAME undef COLUMN_NAME

You might also like