SQL優化三例

2021-08-24 18:42:59 字數 2541 閱讀 2128

sql優化三例

原創:袁光東

在壓力測試時發現,如果原來的查詢在0.1秒之內,那麼在40個併發時,平均速度是3秒。目標要求是所有的查詢必須要在7秒之內。有好幾條sql都是在7秒左右,肯定不能通過壓力測試,必須要優化到2秒之內才有希望通過壓力測試。

(注:主要資料表的記錄數都會超過60w條),所以只能是在專案組內進行sql優化。

(因為某些原因,案例所使用的sql都是經過筆者處理過的,已經不是最原始的sql了。所以不便於貼出詳細的執行計畫)

1、索引很重要

當查詢的記錄數小於表記錄總數的10%時,索引的效果是非常明顯的。

優化前要看執行計畫,去掉不必要的全表掃瞄,找出花費時間的sql。然後加上適當的索引。

2.注意復合索引失效

create index n1 on ht(code,status,ht) ;
在ht表上的ht,code,status三列上已經存在復合索引n1

select * from ht ,qt where ht.ht= qt.ht
發現這個查詢需要20秒左右。

檢視執行計畫時發現,n1這個索引並沒有被使用。

於時,使用提示 index

select index h(n1) from ht h , qt   q where h.ht = q.ht
使用提示後,查詢只需要0.01秒了。

為什麼n1這個索引沒有被使用呢?

原因就是復合索引的問題。

對於復合索引,復合索引的第一列必須出現在where條件中,復合索引才會被使用。

其實按照oracel的說法,「復合索引只有索引的所有列都作為查詢條件時,索引才會被使用」。看來並非如此。

因為當時系統還沒有上線,所以結合實際情況。因為ht列都會出現在查詢的where條件中。所以可以重新建立索引,調整索引列的順序。

create index n1 on ht(hth,code,status)
這樣,查詢只需要0.01秒了。

3.not exists並不是最快的

有一些sql優化經驗的程式設計師都知道。總是該用not exists來代替not in.好像not exists就應該是最快的了。其實不盡然。

使用not exists時一定是要進行關聯子查詢。如果是非關聯子查詢,not exists是沒有意義的。

select * from ht a where not exists ( select id from bills where ht = a.ht and bill_type =1)
因為ht表的資料量非常大。執行執行計畫時發現對ht表的開銷非常大。同時還發現ht表的索引失效了。

考慮如果用外關聯來代替可能會獲得乙個更好的效能

select * from ht a, bills b where a.ht = b.ht(+)

and b.ht is null

and b.type = 1

再次執行執行計畫時,發現兩個表是通過 hash join outer方式進行訪問。

原來的sql需要20秒,優化後的sql只需要0.02秒。

4.合理使用提示

有時使用提示,可以使查詢效率提公升。

h表和q表的記錄數都是60w以上。

select h.a ,h.b,q.a,q.b, q.c from q, h where h.a = q.a and h.b = '' and h.c = ''
在h表的a表有索引。

執行計畫發現對h表的a列上的索引進行了index fast full scan訪問

對q表進行index range scan 和table access by index rowid訪問。

然後進行hash join連線

因為h表都非常大,索引也非常大。就算是對索引進行完全訪問,開銷也很大。

這兩個表的連線方式是比較慢的。

因為在h表是有其它的條件限制,可以過濾掉大部分資料,得到乙個小的結果集,再與q表進行nested loop訪問。這樣效能就會有顯著的提公升。

所以可以加上提示,要求sql按照指定的順序訪問,並且使用nested loop進行連線。

select /* + ordered use_nl(h)/  h.a, h.b, q.a, q.b, q.c from q,h where h.a = q.a

and h.b = ''

and h.c = ''

原來的sql需要7秒,優化後的sql只需要0.7秒。

效能提公升10倍

總結:sql優化是個技術活,也是個體力活。需要耐心,不斷的試驗。

首先要會看執行計畫,迅速的定位效能慢的sql片段。

其次就是對建立適當的索引,儘量減少全表掃瞄

再次就是要對sql進行優化,對優化前和優化後進行對比

最後就是可以使用提示試試

如果不行就需要對環境進行調優化了。如sort_area等。

(因為商業的原因不能把真實的sql語句和執行計畫分析貼出來)

sql優化一例

原sql,查詢總數300,每頁15資料也要8秒 select a from table where date format my time,y m d 2012 08 15 limit 0,15 優化後的sql,查詢總數18000,每頁15的資料只要1秒 select a from table wh...

SQL查詢和優化(三)

給查詢結果排序 select empno,ename,hredate from emp where deptno 10 order by hiredate asc 也可以這樣寫 select empno,ename,hredate from emp where deptno 10 orderby3 ...

測試用例框架優化(三)

在我之前的框架當中,我是把data 類,設計成所有測試類共享得全域性變數。所有的測試類,都是向data 類存資料,取資料。但是在我測試過程當中,會遇到乙個問題 在執行多介面併發 有2 3個介面用例同事執行 同時向data 類存資料就會出現問題 比如審核介面和 提現介面是併發執行的,審核介面用例執行的...