全表掃描是數據庫搜尋表的每一條記錄的過程,直到所有符合給定條件的記錄返回為止。通常在數據庫中,對無索引的表進行查詢一般稱為全表掃描;然而有時候我們即便添加了索引,但當我們的SQL語句寫的不合理的時候也會造成全表掃描。
以下是經常會造成全表掃描的SQL語句及應對措施:
- 使用null做為判斷條件
如:select account from member where nickname = null;
建議在設計字段時盡量將字段的默認值設為0,改為select account where nickname = 0;
- 使用null做為判斷條件
- 左模糊查詢Like %XXX%
如:select account from member where nickname like '%XXX%' 或者 select account from member where nickname like '%XXX'
建議使用select account from member where nickname like 'XXX%',如果必須要用到做查詢,需要評估對當前表全表掃描造成的后果; 劉加東@酷聽說
- 左模糊查詢Like %XXX%
- 使用or做為連接條件
如:select account from member where id = 1 or id = 2;
建議使用union all,改為 select account from member where id = 1 union all select account from member where id = 2;
- 使用or做為連接條件
- 使用in時(not in)
如:select account from member where id in (1,2,3)
如果是連續數據,可以改為select account where id between 1 and 3;當數據較少時也可以參考union用法;
或者:select account from member where id in (select accountid from department where id = 3 ),可以改為select account from member where id exsits (select accountid from department where id = 3)
not in 可以對應 not exists;
- 使用in時(not in)
5.使用not in時
如select account where id not in (1,2,3)6.使用!=或<>時
建議使用 <,<=,=,>,>=,between等;7.對字段有操作時也會引起全表索引
如select account where salary * 0.8 = 1000 或者 select account where sustring(nickname,1,3) = 'zhangxiaolong';8.使用count()時
如select count() from member;
建議使用select count(1) from member;-
9.使用參數做為查詢條件時
如select account from member where nickname = @name
由于SQL語句在編譯執行時并不確定參數,這將無法通過索引進行數據查詢,所以盡量避免;當不規范的寫法造成全表掃描時,會造成CPU和內存的額外消耗,甚至會導致服務器崩潰。在團隊協作中難免會遇到一些初學者,除了安排合理的任務外,資深的工程師也要做好Code Review。否則當我們有海量數據時,不規范的語句會帶來很嚴重的后果,一定要慎重、慎重。