Oracle性能優化5-索引的不足

索引的不足
1.索引開銷
a.訪問開銷
  反問集中導致熱塊的競爭(對最新數據的查詢)
  回表性能取決聚合因子
  索引的訪問開銷,返回幾條數據快,但是返回大量的數據很慢
  全表掃描與全掃描
  建索引會產生全表鎖


b.更新開銷
 索引本身是有序的,更新索引需要重新排序
c.建立開銷
  建索引會產生大量的排序,索引會產生鎖


2.索引使用
a.邏輯失效
  類型轉換,列運算 upper(列)
  /*
  結論:又是一次move table 引發的血案。
  這次案例,是涉及有主外鍵的兩表關聯查詢的性能,索引失效導致NL連接性能下降。
  關於用NL連接的時候一般什麼最快,具體的知識將在後續的表連接課程中描述。


drop table t_p cascade constraints purge;
drop table t_c cascade constraints purge;


CREATE TABLE T_P (ID NUMBER, NAME VARCHAR2(30));
ALTER TABLE T_P ADD CONSTRAINT  T_P_ID_PK  PRIMARY KEY (ID);
CREATE TABLE T_C (ID NUMBER, FID NUMBER, NAME VARCHAR2(30));


ALTER TABLE T_C ADD CONSTRAINT FK_T_C FOREIGN KEY (FID) REFERENCES T_P (ID);


INSERT INTO T_P SELECT ROWNUM, TABLE_NAME FROM ALL_TABLES;
INSERT INTO T_C SELECT ROWNUM, MOD(ROWNUM, 1000) + 1, OBJECT_NAME  FROM ALL_OBJECTS;
COMMIT;


CREATE INDEX IND_T_C_FID ON T_C (FID);


SELECT TABLE_NAME,INDEX_NAME,STATUS FROM USER_INDEXES WHERE INDEX_NAME='IND_T_C_FID';
TABLE_NAME                     INDEX_NAME                     STATUS
------------------------------ ------------------------------ -------
T_C                            IND_T_C_FID                    VALID


--不小心失效了,比如操作了
ALTER TABLE T_C MOVE;


SELECT TABLE_NAME,INDEX_NAME,STATUS FROM USER_INDEXES WHERE INDEX_NAME='IND_T_C_FID';
TABLE_NAME                     INDEX_NAME                     STATUS
------------------------------ ------------------------------ --------
T_C                            IND_T_C_FID                    UNUSABLE


--結果查詢性能是這樣的:
SET LINESIZE 1000
SET AUTOTRACE TRACEONLY
SELECT A.ID, A.NAME, B.NAME FROM T_P A, T_C B WHERE A.ID = B.FID AND A.ID = 880;
執行計劃
------------------------------------------------------------------------------------------
| Id  | Operation                    | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |           |    25 |  1500 |   111   (1)| 00:00:02 |
|   1 |  NESTED LOOPS                |           |    25 |  1500 |   111   (1)| 00:00:02 |
|   2 |   TABLE ACCESS BY INDEX ROWID| T_P       |     1 |    30 |     0   (0)| 00:00:01 |
|*  3 |    INDEX UNIQUE SCAN         | T_P_ID_PK |     1 |       |     0   (0)| 00:00:01 |
|*  4 |   TABLE ACCESS FULL          | T_C       |    25 |   750 |   111   (1)| 00:00:02 |
------------------------------------------------------------------------------------------
   3 - access("A"."ID"=880)
   4 - filter("B"."FID"=880)
統計信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        394  consistent gets
          0  physical reads
          0  redo size
       3602  bytes sent via SQL*Net to client
        459  bytes received via SQL*Net from client
          6  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         72  rows processed   
         
---將失效索引重建後
ALTER INDEX IND_T_C_FID   REBUILD;
查詢性能是這樣的:
SELECT A.ID, A.NAME, B.NAME FROM T_P A, T_C B WHERE A.ID = B.FID AND A.ID = 880;
執行計劃
--------------------------------------------------------------------------------------------
| Id  | Operation                    | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |             |    72 |  4320 |    87   (0)| 00:00:02 |
|   1 |  NESTED LOOPS                |             |    72 |  4320 |    87   (0)| 00:00:02 |
|   2 |   TABLE ACCESS BY INDEX ROWID| T_P         |     1 |    30 |     0   (0)| 00:00:01 |
|*  3 |    INDEX UNIQUE SCAN         | T_P_ID_PK   |     1 |       |     0   (0)| 00:00:01 |
|   4 |   TABLE ACCESS BY INDEX ROWID| T_C         |    72 |  2160 |    87   (0)| 00:00:02 |
|*  5 |    INDEX RANGE SCAN          | IND_T_C_FID |    72 |       |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
   3 - access("A"."ID"=880)
   5 - access("B"."FID"=880)
統計信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         81  consistent gets
          0  physical reads
          0  redo size
       3602  bytes sent via SQL*Net to client
        459  bytes received via SQL*Net from client
          6  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         72  rows processed      
b.物理失效
  索引壞了,分區導致全局索引失效,誤刪除
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章