。檢查被索引的列或組合索引的首列是否出現在pl/sql語句的where子句中,這是「執行計畫」能用到相關索引的必要條件。
。看採用了哪種型別的連線方式。oracle的共有sort merge join(smj)、hash join(hj)和nested loop join(nl)。在兩張表連線,且內錶的目標列上建有索引時,只有nested loop才能有效地利用到該索引。smj即使相關列上建有索引,最多只能因索引的存在,避免資料排序過程。hj由於須做hash運算,索引的存在對資料查詢速度幾乎沒有影響。
。看連線順序是否允許使用相關索引。假設表emp的deptno列上有索引,表dept的列deptno上無索引,where語句有emp.deptno=dept.deptno條件。在做nl連線時,emp做為外表,先被訪問,由於連線機制原因,外表的資料訪問方式是全表掃瞄,emp.deptno上的索引顯然是用不上,最多在其上做索引全掃瞄或索引快速全掃瞄。
。是否用到系統資料字典表或檢視。由於系統資料字典表都未被分析過,可能導致極差的「執行計畫」。但是不要擅自對資料字典表做分析,否則可能導致死鎖,或系統效能下降。
。索引列是否函式的引數。如是,索引在查詢時用不上。
。是否存在潛在的資料型別轉換。如將字元型資料與數值型資料比較,oracle會自動將字元型用to_number()函式進行轉換,從而導致上一種現象的發生。
。是否為表和相關的索引蒐集足夠的統計資料。對資料經常有增、刪、改的表最好定期對錶和索引進行分析,可用sql語句「analyze table ***x compute statistics for all indexes;」。oracle掌握了充分反映實際的統計資料,才有可能做出正確的選擇。
。索引列的選擇性不高。 我們假設典型情況,有表emp,共有一百萬行資料,但其中的emp.deptno列,資料只有4種不同的值,如10、20、30、40。雖然emp資料行有很多,oracle預設認定表中列的值是在所有資料行均勻分布的,也就是說每種deptno值各有25萬資料行與之對應。假設sql搜尋條件deptno=10,利用deptno列上的索引進行資料搜尋效率,往往不比全表掃瞄的高。
。索引列值是否可為空(null)。如果索引列值可以是空值,在sql語句中那些要返回null值的操作,將不會用到索引,如count(*),而是用全表掃瞄。這是因為索引中儲存值不能為全空。
。看是否有用到並行查詢(pqo)。並行查詢將不會用到索引。
。如果從以上幾個方面都查不出原因的話,我們只好用採用在語句中加hint的方式強制oracle使用最優的「執行計畫」。 hint採用注釋的方式,有行注釋和段注釋兩種方式。 如我們想要用到a表的ind_col1索引的話,可採用以下方式: 「select /*+ index(a ind_col1)*/ * from a where col1 = ***;"
如何遮蔽索引
語句的執行計畫中有不良索引時,可以人為地遮蔽該索引,方法:
。數值型:在索引欄位上加0,例如
select * from emp where emp_no+0 = v_emp_no;
。字元型:在索引欄位上加『』,例如
select * from tg_cdr01 where msisdn||』』=v_msisdn;
索引失效的幾種情況
使用explain sql 可檢視mysql執行計畫 type為掃瞄型別,key為使用索引型別 1.使用了or 除非or的列都加上了索引 2.聯合索引 未符合索引字段順序 3.like查詢 使用前 不走索引 4.字元型不加引號 資料庫自動轉換成數值型 資料型別不統一 不走索引 5.sql中使用函式,...
索引失效的幾種情況
1.有or必全有索引 2.復合索引未用左列字段 3.like以 開頭 4.需要型別轉換 5.where中索引列有運算 6.where中索引列使用了函式 not in 或 not exists 7.如果mysql覺得全表掃瞄更快時 資料少 1.唯一性差 2.頻繁更新的字段不用 更新索引消耗 3.whe...
MySQL索引失效的幾種情況
更準確的說,單列索引不儲存null值,復合索引不儲存全為null的值。索引不能儲存null,所以對這列採用is null條件時,因為索引上根本 沒null值,不能利用到索引,只能全表掃瞄。為什麼索引列不能存null值?將索引列值進行建樹,其中必然涉及到諸多的比較操作。null值的特殊性就在於參與的運...