常數與資料行值之間的比較,若常數值相對於資料行類型超出範圍或類型錯誤,現在會在查詢最佳化期間處理一次,而不是在執行期間逐列處理。可以這種方式處理的比較為 >、>=、<、<=、<>/!=、= 和 <=>。
考量由下列陳述式建立的資料表
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)且具有非零的小數部分,則它們不能相等;請據此折疊。對於其他比較,請根據符號向上或向下捨入為整數值,然後執行範圍檢查,並按照先前針對整數與整數比較所述的方式處理。若
REAL值太小而無法表示為DECIMAL,則根據符號捨入為 .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資料行或使用日期或時間類型的資料行時。在準備陳述的準備階段期間,儘管可以在實際執行準備陳述的最佳化階段應用。這是由於在陳述準備期間,常數的值尚未知。