在數據庫操作中,一個全表掃描(full table scan)可能是整個應用的瓶頸,因此,我們儘量
要避免不必要的全表掃描。而如果你發現一條sql是全表掃描,一般的解決步驟是:
1、運行執行計劃獲得具體的sql語句查詢分析:
方法:explain sql;
分析:至少能或得這些信息,1、表的join順序(按計劃的上到下join), 2、是否
使用索引,3、可能會使用的索引
2、添加對應的索引,或是重寫查詢sql,或更換join順序等
3、如果查詢對當前的結構不滿意,可以考慮重建表
下面分別說一下全表掃描可能發生的情形:
1、在on或者where字句中,使用的列沒有索引,可以考慮加一個索引
2、表很小,大約少於10行,這個沒有什麼危害,因爲即使你有索引,優化器也會判斷
在邊讀索引邊取數據時,直接全表掃描快些
3、你在一個where字句中使用含有索引的列,但這個列的值很集中化,比如字段 gender,
這個的值就兩個值male 和 female,如果使用索引反而會慢些,不使用索引會更快,這
種情況不用擔心
4、這個跟第三條類似,就是當你的一個索引,他的每個鍵對應多個值,即基數很低
(low cardinality),因此可能會選擇全表掃描
下面說一下對與避免發生全部掃描的時間:
1、對於使用or查詢的語句,這種查詢可能會產生全表掃描,他的策略是以一個一個比較
如果符合要求,則選出來,但這樣的操作會很慢,我們可以用union來做這樣的查詢,
當然union要快的前提是,你對兩個條件都有索引,如:
select * from table1 where key1 < 10 or key2 > 60
可以更改爲:
select * from table1 where key1 < 10 union select * from table1 where key2 >60
2、對於使用memory引擎的,建立索引時,默認是hash索引,這個的支出的訪問單行數據很快,
但如果你有類似的範圍操作如>= , <= , between 時,可以考慮建立索引用btree類型的,方法爲:
create index index_name on table(col_name) using btree;
3、當你分析確定必須使用某個索引,但執行計劃卻不使用該索引,可以使用force index,方法爲:
select * from table_name force index index_name where clause
4、使用analyze table table_name來更新索引的鍵的分佈,這個會影響jion表的順序