SQL優化之建立索引二

2021-08-30 00:08:23 字數 1573 閱讀 7525

降龍十八掌

第一掌 避免對列的操作

任何對列的操作都可能導致全表掃瞄,這裡所謂的操作包括資料庫函式、計算表示式等等,查詢時要盡可能將操作移至等式的右邊,甚至去掉函式。

例1:下列sql條件語句中的列都建有恰當的索引,但30萬行資料情況下執行速度卻非常慢:

select * from record where substrb(cardno,1,4)='5378'(13秒)

select * from record where amount/30< 1000(11秒)

select * from record where to_char(actiontime,'yyyymmdd')='19991201'(10秒)

由於where子句中對列的任何操作結果都是在sql執行時逐行計算得到的,因此它不得不進行表掃瞄,而沒有使用該列上面的索引;如果這些結果在查詢編譯時就能得到,那麼就可以被sql優化器優化,使用索引,避免表掃瞄,因此將sql重寫如下:

select * from record where cardno like '5378%'(< 1秒)

select * from record where amount < 1000*30(< 1秒)

select * from record where actiontime= to_date ('19991201' ,'yyyymmdd')(< 1秒)

差別是很明顯的!

第二掌 避免不必要的型別轉換

需要注意的是,盡量避免潛在的資料型別轉換。如將字元型資料與數值型資料比較,oracle會自動將字元型用to_number()函式進行轉換,從而導致全表掃瞄。

例2:表tab1中的列col1是字元型(char),則以下語句存在型別轉換:

select col1,col2 from tab1 where col1>10,

應該寫為: select col1,col2 from tab1 where col1>'10'。

第三掌 增加查詢的範圍限制

增加查詢的範圍限制,避免全範圍的搜尋。

例3:以下查詢表record 中時間actiontime小於2023年3月1日的資料:

select * from record where actiontime < to_date ('20010301' ,'yyyymm')

查詢計畫表明,上面的查詢對錶進行全表掃瞄,如果我們知道表中的最早的資料為2023年1月1日,那麼,可以增加乙個最小時間,使查詢在乙個完整的範圍之內。修改如下: select * from record where

actiontime < to_date ('20010301' ,'yyyymm')

and actiontime > to_date ('20010101' ,'yyyymm')

後 一種sql語句將利用上actiontime欄位上的索引,從而提高查詢效率。把'20010301'換成乙個變數,根據取值的機率,可以有一半以上的機 會提高效率。同理,對於大於某個值的查詢,如果知道當前可能的最大值,也可以在where子句中加上 「and 列名< max(最大值)」。

SQL優化之建立索引一

基於索引的sql語句優化之降龍十八掌 塵封往事 引用功能被關閉了。前言 客 服業務受到sql語句的影響非常大,在規模比較大的局點,往往因為乙個小的sql語句不夠優化,導致資料庫效能急劇下降,小型機idle所剩無幾,應用服 務器斷連 超時,嚴重影響業務的正常執行。因此,稱低效的sql語句為客服業務的 ...

SQL優化之建立索引五

第十四掌 使用基於函式的索引 前面談到任何對列的操作都可能導致全表掃瞄,例如 select from emp where substr ename,1,2 sm 但是這種查詢在客服系統又經常使用,我們可以建立乙個帶有substr函式的基於函式的索引,create index emp ename su...

SQL優化之建立索引六

第十八掌 決定使用全表掃瞄還是使用索引 和 所有的秘笈一樣,最後一招都會又回到起點,最後我們來討論一下是否需要建立索引,也許進行全表掃瞄更快。在大多數情況下,全表掃瞄可能會導致更多的物理磁 盤輸入輸出,但是全表掃瞄有時又可能會因為高度並行化的存在而執行的更快。如果查詢的表完全沒有順序,那麼乙個要返回...