一、建立合適的索引
在常用過濾條件、表連接的字段建立索引。但并不是所有索引對查詢都有效,MySQL如果掃描數據超過30%,都會走全表。
二、在where條件中優化
1.Oracle數據庫where條件是從后往前執行,和MySQL數據庫順序相反,可把大過濾的條件放在最先執行的位置
2.避免在 where 子句中使用 or 、表達式操作、函數操作、 !=或<> 操作符、前置百分號等5種情況,否則將導致引擎放棄使用索引而進行全表掃描
select id from t where num=10 or num=20
可以這樣查詢:
select id from t where num=10
union all
select id from t where num=20
select id from t where num/2=100
應改為:
select id from t where num=100*2
select id from t where substring(name,1,3)='abc' --name以abc開頭的id
select id from t where datediff(day,createdate,'2005-11-30')=0 --'2005-11-30'生成的id
應改為:
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
select id from t where name like ‘%abc%’
若要提高效率,可以考慮全文檢索。
3.exists替代in
很多時候用 exists 代替 in 是一個好的選擇:
select num from a where num in(select num from b)
用下面的語句替換:
select num from a where exists(select 1 from b where num=a.num)
4.不要使用 select * from t,用具體的字段列表代替“*”,不要返回用不到的任何字段。
三、表連接方式優化,盡量避免NESTED LOOP嵌套循環
一般而言,使用nested loop要用數據量小的表作為驅動表(準確說,應該是經過限制條件后返回結果集行數較少的應作為驅動表)
,這樣復雜度O(m*log(n)),即驅動表數據記錄m要小。
或者改變join的方式,使用/* +use_hash(t1,t2) */變為hash join,要比nested loop outer快很多。
四、考慮使用臨時表或表變量存放中間結果
五、建立分區表
表進行分區后,邏輯上表仍然是一張完整的表,只是將表中的數據在物理上存放到多個表空間(物理文件上),這樣查詢數據時,不至于每次都掃描整張表。