1.應盡量避免在where子句中對字段進行null值判斷,否則將導致引擎放棄使用索引而進行全表掃描2.應盡量避免在where子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。 優化器將無法通過索引來確定將要命中的行數,因此需要搜索該表的所有行。3.應盡量避免在where子句中使用 or 來連接條件,否則將導致引擎放棄使用索引而進行全表掃描,如: 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=204.in和not in也要慎用,因為IN會使系統無法使用索引,而只能直接搜索表中的數據。如: select id from t where num in(1,2,3) 對于連續的數值,能用 between 就不要用 in 了: select id from t where num between 1 and 3 很多時候用exists是一個好的選擇: 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)5.盡量避免在索引過的字符數據中,使用非打頭字母搜索。這也使得引擎無法利用索引。 見如下例子: SELECT * FROM T1 WHERE NAME LIKE '%L%' SELECT * FROM T1 WHERE SUBSTING(NAME,2,1)='L' SELECT * FROM T1 WHERE NAME LIKE 'L%' 即使NAME字段建有索引,前兩個查詢依然無法利用索引完成加快操作,引擎不得不對全表所有數據逐條操作來完成任務。 而第三個查詢能夠使用索引來加快操作。6.必要時強制查詢優化器使用某個索引,如在where子句中使用參數,也會導致全表掃描。因為SQL只有在運行時才會解析局部變量, 但優化程序不能將訪問計劃的選擇推遲到運行時;它必須在編譯時進行選擇。然而,如果在編譯時建立訪問計劃,變量的值還是未知的, 因而無法作為索引選擇的輸入項。如下面語句將進行全表掃描: select id from t where num=@num 可以改為強制查詢使用索引: select id from t with(index(索引名)) where num=@num7.應盡量避免在where子句中對字段進行表達式操作,這將導致引擎放棄使用索引而進行全表掃描。 即:任何對列的操作都將導致表掃描,它包括數據庫函數、計算表達式等等,查詢時要盡可能將操作移至等號右邊。8.應盡量避免在where子句中對字段進行函數操作,這將導致引擎放棄使用索引而進行全表掃描。9.不要在where子句中的“=”左邊進行函數、算術運算或其他表達式運算,否則系統將可能無法正確使用索引。10.在使用索引字段作為條件時,如果該索引是復合索引,那么必須使用到該索引中的第一個字段作為條件時才能保證系統使用該索引, 否則該索引將不會被使用,并且應盡可能的讓字段順序與索引順序相一致。11.能用DISTINCT的就不用GROUP BY12.能用UNION ALL就不要用UNION13.盡量不要用SELECT INTO語句。SELECT INOT語句會導致表鎖定,阻止其他用戶訪問該表。14.使用視圖加速查詢,把表的一個子集進行排序并創建視圖,有時能加速查詢。它有助于避免多重排序 操作,而且在其他方面還能簡化優化器的工作。15.充分利用連接條件,在某種情況下,兩個表之間可能不只一個的連接條件,這時在 WHERE 子句中將連接條件完整的寫上,有可能大大提高查詢速度。 例: SELECT SUM(A.AMOUNT) FROM ACCOUNT A,CARD B WHERE A.CARD_NO = B.CARD_NO SELECT SUM(A.AMOUNT) FROM ACCOUNT A,CARD B WHERE A.CARD_NO = B.CARD_NO AND A.ACCOUNT_NO=B.ACCOUNT_NO 第二句將比第一句執行快得多。16.避免使用不兼容的數據類型。例如float和int、char和varchar、binary和varbinary是不兼容的。 數據類型的不兼容可能使優化器無法執行一些本來可以進行的優化操作。例如: SELECT name FROM employee WHERE salary > 60000 在這條語句中,如salary字段是money型的,則優化器很難對其進行優化,因為60000是個整型數。 我們應當在編程時將整型轉化成為錢幣型,而不要等到運行時轉化。