全表掃描!你的數據庫有點弱智

全表掃描(Full Table Scan)就是數據庫爲了檢索到咱們查找的數據而逐行的去掃描表中的全部記錄。很明顯,全表掃描是一種很是慢的SQL查詢。想象一下,對一張百萬級的表進行全表掃描性能有多差!使用索引能夠有效避免全表掃描。sql

讓咱們看一些會形成進行全表掃描的狀況:數據庫

統計信息尚未更新

一般,數據庫的統計信息要與表數據和索引數據保持一致。可是,由於一些緣由致使表或索引的統計信息沒有及時更新,結果就有可能形成全表掃描。這是由於大多數RDBMS(關係型數據庫)的查詢優化器會根據這些統計信息來計算是否應該使用索引。若是沒有這些統計信息或統計信息不許確,RDBMS可能會錯誤的認爲執行全表掃描比使用索引更高效。性能

沒有WHRER子句

若是查詢語句沒有過濾結果集的WHRER子句,會執行全表掃描。優化

沒有使用索引

有些狀況,即便建立了索引還會執行全表掃描。spa

雖然查詢語句有WHERE子句,可是WHERE子句中使用的列沒有匹配索引的"領導列"(leading column),就會執行全表掃描。領導列又稱最左列(leftmost column),見下一節「最左前綴匹配原則」。.net

即便WHERE子句中使用了索引的最左列,仍有可能執行全表掃描。這通常是因爲WHRE子句中使用了「比較」操做,而阻止了數據庫使用索引!下面列舉幾個會形成這種狀況的例子:code

  • 使用不等於操做(!= 或 <>)。blog

    例如: WHERE NAME <> 'Jesus'索引

    由於索引只能用於查找表中有什麼,而不能用於查找表中沒有什麼。字符串

  • 使用`NOT`操做符。

    例如:WHERE NOT NAME 'Jesus' 。緣由同上。

  • 通配符出如今字符串比較的開始位置。

    例如:WHERE NAME LIKE '%programmer%' 。

    以哪一個字母開始都不清楚,索引也無能爲力了。

最左前綴匹配原則

對於多列的混合索引(composite index),只有符合最左前綴(leftmost prefix)的索引才能被查詢優化器使用。好比,某個3列的混合索引(col1,col2,col3),只有下面三種狀況可使用到索引: (col1), (col1, col2),和 (col1, col2, col3)。

對於下面的查詢語句:

SELECT * FROM tbl_name WHERE col1=val1;
SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;

SELECT * FROM tbl_name WHERE col2=val2;
SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3;

只有前兩個SELECT語句使用到了索引,第3個和第4個查詢雖然使用了索引列,可是(col2)和(col2,col3)不是混合索引(col1, col2, col3)的最左前綴。

 

相關閱讀:

      《數據庫索引的工做原理》

      《不知道"選擇性"怎麼能說懂索引呢》

相關文章
相關標籤/搜索