高效sql

高效的sql查詢

海量數據查詢總是會感覺很慢,特別當好幾張海量表關聯的時候更是如此。下面是收集的一些有效的tips。

1、使用index來使你的查詢更快。

  a)儘量別使用不等操作符(!=或者<>)因爲index可以告訴你表的某個位置有什麼,但是它沒辦法告訴你那裏沒有什麼。另外: the index is used when optimizer_goal is FIRST_ROWS。所以下面的寫法比較忌諱:

Select * from emp where empno != 0;

  b)儘量不要在字段上使用函數。一旦使用了函數, 優化器就沒辦法使用字段上的index了除非是functional index。

Select * from emp where substr(ename, 1, 1) = ‘K’;

2、不要對不同類型的數據進行比較。比如整型和字符型的直接進行比較。

Select * from emp where empno = ‘7788’;

3、使用exists函數代替in函數

Select product_id, qty from product where product_id = 167 and 

item_no in (select item_no from items);   =====>

Select product_id, qty from product a where product_id = 167 and

exists (select ‘x’ from items b where b.item_no = a.item_no);

4、使用hint來指導優化器使用更好的執行計劃。

5、如果能精確匹配就絕對不要使用模糊匹配,有一個總的原則,你給的條件越精確,所涉及的記錄數越少,則查詢越迅速。

比如下面的寫法:"COMCODE" like '3201%'就很慢,如果改成substr("COMCODE",1,4)='3201'則效率提升很多,而且效果是一樣的。

6、Early elimination of candidate rows儘早消除候選行。

A candidate row is a row from a table or subquery that could potentially be returned in the result set. To actually be returned it must satisfiy the WHERE and JOIN conditions.』翻譯:一個候選行是來自一張表或自查詢的有可能作爲查詢結果返回的行,但是返回的前提是該行必須滿足where和join條件。其實我的理解就是你必須讓儘可能少的記錄參與連接操作。如果能在表連接前過濾掉的數據,就不要在表連接之後再來過濾。

如果儘早消除了候選行,那麼後續步驟需要的操作和資源都減少。假定下面的invoice_lines是一張海量表: 

Select v.vendor_num, I.invoice_num, sum (l.amount) from vendors v, invoices I, 

invoice_lines l where

v.vendor_name = ‘ACME’ and l.vendor_num = v.vendor_num and I.vendor_num = 

l.vendor_num and I.invoice_num = l.invoice_num and

i.paid = ‘N’ group by v.vendor_num, I.invoice_num order by I.invoice_num;  

==========>

Select v.vendor_num, I.invoice_num, sum (l.amount) from vendors v, invoices I, 

invoice_lines l where

v.vendor_name = ‘ACME’ and I.vendor_num = v.vendor_num and I.paid = ‘N’ and 

l.vendor_num = I.vendor_num and l.invoice_num = I.invoice_num

Group by v.vendor_num = I.invoice_num order by I.invoice_num;

7、Minimize the number of throwaway rows儘量減少一次性行數。何爲throwaway rows希望有人告知。我的直覺就是第一輪過濾就直接排除掉的記錄,就沒明白與candidate rows有何區別。

• Compare the number of rows from the two input row sources 

with the number of rows from the join operation. If both input 

row sources have more rows than the join operation has, you 

have identified a throwaway of rows.

• Example

Rows Operation

100 NESTED LOOPS

45 TABLE ACCESS (…) OF our_outer_table

4530 TABLE ACCESS (…) OF our_inner_table

• Select the table with less number of records as driving table

8、儘量使用對應數據庫供應商提供的函數,因爲他們很可能對相關函數進行了性能優化。比如:在沒有index的情況下,oracle中不要使用like '%negative%',建議用instr(field,'negative')來代替,海量數據中有明顯優勢。

9、儘量不要在表的字段上進行運算,這不單單會導致索引失效。比如

 

trunc(to_date("HANDLETIME", 'YYYY-MM-DD hh24:mi:ss'),

             'dd') >= trunc(sysdate, 'dd') - 7  ======>

 "HANDLETIME">=TO_CHAR(TRUNC(sysdate,'dd')-7,'YYYY-MM-DD hh24:mi:ss')

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章