常數與資料行值之間的比較,其中常數值相對於資料行類型超出範圍或類型錯誤,現在在查詢最佳化期間處理一次,而不是在執行期間逐列處理。可以以此方式處理的比較是 >
、>=
、<
、<=
、<>
/!=
、=
和 <=>
。
請考慮以下陳述式建立的資料表
CREATE TABLE t (c TINYINT UNSIGNED NOT NULL);
查詢 SELECT * FROM t WHERE c < 256
中的 WHERE
條件包含整數常數 256,該常數對於 TINYINT UNSIGNED
資料行來說超出範圍。先前,這是透過將兩個運算元都視為較大的類型來處理,但現在,由於 c
的任何允許值都小於常數,因此 WHERE
表達式可以改為摺疊為 WHERE 1
,因此查詢會改寫為 SELECT * FROM t WHERE 1
。
這使得最佳化工具可以完全移除 WHERE
表達式。如果資料行 c
可為 Null (也就是說,僅定義為 TINYINT UNSIGNED
),則查詢會像這樣改寫
SELECT * FROM t WHERE ti IS NOT NULL
對於與支援的 MySQL 資料行類型比較的常數,會執行如下的摺疊
整數資料行類型。 整數類型與以下類型的常數進行比較,如此處所述
整數值。 如果常數超出資料行類型的範圍,則比較會摺疊為
1
或IS NOT NULL
,如已顯示的。如果常數是範圍邊界,則比較會摺疊為
=
。例如 (使用與已定義的相同資料表)mysql> EXPLAIN SELECT * FROM t WHERE c >= 255; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: t partitions: NULL type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 5 filtered: 20.00 Extra: Using where 1 row in set, 1 warning (0.00 sec) mysql> SHOW WARNINGS; *************************** 1. row *************************** Level: Note Code: 1003 Message: /* select#1 */ select `test`.`t`.`ti` AS `ti` from `test`.`t` where (`test`.`t`.`ti` = 255) 1 row in set (0.00 sec)
浮點或定點數值。 如果常數是十進位類型之一(例如
DECIMAL
、REAL
、DOUBLE
或FLOAT
)並且具有非零的小數部分,則它不能相等;因此進行折疊。對於其他比較,根據符號向上或向下捨入為整數值,然後執行範圍檢查,並按照已描述的整數-整數比較方式處理。一個太小而無法表示為
DECIMAL
的REAL
值,會根據符號捨入為 .01 或 -.01,然後作為DECIMAL
處理。字串類型。 嘗試將字串值解釋為整數類型,然後將比較處理為整數值之間的比較。如果失敗,則嘗試將該值作為
REAL
處理。
DECIMAL 或 REAL 欄位。 十進位類型與下列類型的常數進行比較,如下所述
整數值。 針對欄位值的整數部分執行範圍檢查。如果沒有產生折疊結果,則將常數轉換為具有與欄位值相同小數位數的
DECIMAL
,然後作為DECIMAL
檢查(請參閱下一個)。DECIMAL 或 REAL 值。 檢查溢位(也就是說,常數的整數部分中的位數是否超出欄位的十進位類型所允許的範圍)。如果是,則折疊。
如果常數的小數部分有效位數多於欄位類型,則截斷常數。如果比較運算子是
=
或<>
,則折疊。如果運算子是>=
或<=
,則因截斷而調整運算子。例如,如果欄位的類型是DECIMAL(3,1)
,則SELECT * FROM t WHERE f >= 10.13
會變成SELECT * FROM t WHERE f > 10.1
。如果常數的小數位數少於欄位的類型,則將其轉換為具有相同位數的常數。對於
REAL
值的下溢(也就是說,小數部分位數太少而無法表示它),將常數轉換為十進位 0。字串值。 如果該值可以解釋為整數類型,則將其作為整數類型處理。否則,嘗試將其作為
REAL
處理。
FLOAT 或 DOUBLE 欄位。
FLOAT(
或m
,n
)DOUBLE(
值與常數進行比較時,處理方式如下m
,n
)如果該值超出欄位的範圍,則折疊。
如果該值的小數部分超過
n
位,則截斷,並在折疊期間進行補償。對於=
和<>
比較,按照先前所述折疊為TRUE
、FALSE
或IS [NOT] NULL
;對於其他運算子,則調整運算子。如果該值的整數位數超過
m
位,則折疊。
限制。 在下列情況下,無法使用此最佳化
使用
BETWEEN
或IN
進行比較時。使用
BIT
欄位或使用日期或時間類型的欄位時。在預備語句的準備階段期間,儘管它可以在實際執行預備語句時的最佳化階段應用。這是由於在語句準備期間,常數的值尚未知。