MySQL 8.0的新增功能探索-强制转换操作

  • 查询演员表注入。 在8.0.18及更高版本中,MySQL将强制转换操作注入表达式和条件内的查询项树中,在该表达式和条件中,参数的数据类型与预期的数据类型不匹配。这对查询结果或执行速度没有影响,但是使查询的执行等同于符合SQL标准的查询,同时保持了与MySQL早期版本的向后兼容性。

现在这样的隐式转换的时间类型(之间执行DATEDATETIMETIMESTAMPTIME)和数字类型(SMALLINTTINYINTMEDIUMINTINT/ INTEGERBIGINT; DECIMAL/ NUMERIC; FLOATDOUBLEREALBIT),只要他们正在使用任何标准的数字比较运算符(相较=>=><<=<>/ !=,要么 <=>)。在这种情况下,任何尚未为a的值 DOUBLE都将强制转换为1。现在还执行强制转换注入,以比较DATETIME值与 DATETIME值,其中,必要时将参数强制转换 为 DATETIME

从MySQL 8.0.21开始,在将字符串类型与其他类型进行比较时,也会执行此类转换。被投字符串类型包括CHARVARCHARBINARYVARBINARYBLOBTEXTENUM,和 SET。将字符串类型的值与数字类型或进行比较时 YEAR,字符串强制转换为 DOUBLE; 如果其他参数的类型不是FLOATDOUBLE或者REAL,它也投来 DOUBLE。在将字符串类型与a DATETIMETIMESTAMP value 进行比较时 ,字符串将强制转换为DATETIME; 将字符串类型与比较时DATE,字符串被强制转换为DATE

因此能够看到通过查看的输出时石膏注入到一个给定的查询EXPLAIN ANALYZEEXPLAIN FORMAT=JSON或者,如下所示,EXPLAIN FORMAT=TREE

mysql> CREATE TABLE d (dt DATETIME, d DATE, t TIME);
Query OK, 0 rows affected (0.62 sec)

mysql> CREATE TABLE n (i INT, d DECIMAL, f FLOAT, dc DECIMAL);
Query OK, 0 rows affected (0.51 sec)

mysql> CREATE TABLE s (c CHAR(25), vc VARCHAR(25),
-> bn BINARY(50), vb VARBINARY(50), b BLOB, t TEXT,
-> e ENUM('a', 'b', 'c'), se SET('x' ,'y', 'z'));
Query OK, 0 rows affected (0.50 sec)

mysql> EXPLAIN FORMAT=TREE SELECT * from d JOIN n ON d.dt = n.i\G
*************************** 1\. row ***************************
EXPLAIN: -> Inner hash join (cast(d.dt as double) = cast(n.i as double))
(cost=0.70 rows=1)
-> Table scan on n (cost=0.35 rows=1)
-> Hash
-> Table scan on d (cost=0.35 rows=1)

mysql> EXPLAIN FORMAT=TREE SELECT * from s JOIN d ON d.dt = s.c\G
*************************** 1\. row ***************************
EXPLAIN: -> Inner hash join (d.dt = cast(s.c as datetime(6))) (cost=0.72 rows=1)
-> Table scan on d (cost=0.37 rows=1)
-> Hash
-> Table scan on s (cost=0.35 rows=1)

1 row in set (0.01 sec)

mysql> EXPLAIN FORMAT=TREE SELECT * from n JOIN s ON n.d = s.c\G
*************************** 1\. row ***************************
EXPLAIN: -> Inner hash join (cast(n.d as double) = cast(s.c as double)) (cost=0.70 rows=1)
-> Table scan on s (cost=0.35 rows=1)
-> Hash
-> Table scan on n (cost=0.35 rows=1)

1 row in set (0.00 sec)

也可以通过执行看到这种强制类型转换EXPLAIN [FORMAT=TRADITIONAL],在这种情况下,也有必要SHOW WARNINGS在执行EXPLAIN语句之后 发出。