編寫高性能的SQL語句注意事項
前言
在應用系統開發初期,由于開發數據庫數據比較少,對于查詢SQL語句,復雜視圖的的編寫等體會不出SQL語句各種寫法的性能優劣,但是如果將應 用系統提交實際應用后,隨著數據庫中數據的增加,系統的響應速度就成為目前系統需要解決的最主要的問題之一。系統優化中一個很重要的方面就是SQL語句的 優化。對于海量數據,劣質SQL語句和優質SQL語句之間的速度差別可以達到上百倍,可見對于一個系統不是簡單地能實現其功能就可,而是要寫出高質量SQL語句,提高系統的可用性。
在多數情況下,數據庫使用索引來更快地遍歷表,優化器主要根據定義的索引來提高性能。但是,如 果在SQL語句的where子句中寫的SQL代碼不合理,就會造成優化器刪去索引而使用全表掃描,一般就這種SQL語句就是所謂的劣質SQL語句。在編寫 SQL語句時我們應清楚優化器根據何種原則來刪除索引,這有助于寫出高性能的SQL語句。
索引有哪些種類?
常見的索引有B-TREE索引、位圖索引、全文索引。
B-TREE索引也稱為平衡樹索引(Balance Tree),它是一種按字段排好序的樹形目錄結構,主要用于提升查詢性能和唯一約束支持;B-TREE索引包括很多擴展類型,如組合索引、反向索引、函數索引等等;B-TREE索引的內容包括根節點、分支節點、葉子節點。
位圖索引一般用于數據倉庫應用。
一個表中可以建多個索引,就如一本字典可以建多個目錄一樣(按拼音、筆劃、部首等等)。
一個索引也可以由多個字段組成,稱為組合索引,如上圖就是一個按部首+筆劃的組合目錄。
SQL語句中,什么條件會使用索引?
當字段上建有索引時,通常以下情況會使用索引:
INDEX_COLUMN = ? (或者>、>=、<、<=)
INDEX_COLUMN between ? and ?
INDEX_COLUMN IN (?,?,...,?)
INDEX_COLUMN like ?||'%'(后導模糊查詢)
T1. INDEX_COLUMN=T2. COLUMN1(兩個表通過索引字段關聯)
SQL語句中,什么條件不會使用索引?
查詢條件 不能使用索引原因
INDEX_COLUMN <> ?
INDEX_COLUMN not in (?,?,...,?) 不等于操作不能使用索引
function(INDEX_COLUMN) = ?
INDEX_COLUMN + 1 = ?
INDEX_COLUMN || 'a' = ? 經過普通運算或函數運算后的索引字段不能使用索引,但是經過函數運算字段的字段要使用可以使用函數索引
INDEX_COLUMN like '%'||?
INDEX_COLUMN like '%'||?||'%' 含前導模糊查詢的Like語法不能使用索引
INDEX_COLUMN is null B-TREE索引里不保存字段為NULL值記錄,因此IS NULL不能使用索引
NUMBER_INDEX_COLUMN='12345'
CHAR_INDEX_COLUMN=12345 在做數值比較時需要將兩邊的數據轉換成同一種數據類型,如果兩邊數據類型不同時會對字段值隱式轉換,相當于加了一層函數處理,所以不能使用索引。
a.INDEX_COLUMN=a.COLUMN_1 給索引查詢的值應是已知數據,不能是未知字段值。
注意:有時候我們會使用多個字段的組合索引,如果查詢條件中第一個字段不能使用索引,那整個查詢也不能使用索引。
|
|