MySQL 8.0.21引入了在创建或更新用户账户时设置用户评论和用户属性的功能。用户评论由作为COMMENT子句参数传递的任意文本组成,通过CREATE USER或ALTER USER语句使用。用户属性由以JSON对象形式传递的数据组成,作为ATTRIBUTE子句参数传递给这两个语句之一。属性可以包含JSON对象表示法中的任何有效的键值对。在单个CREATE USER或ALTER USER语句中只能使用COMMENT或ATTRIBUTE中的一个。
用户评论和用户属性在内部作为一个JSON对象存储在一起,其中评论文本作为键为"comment"的元素的值。这些信息可以从Information Schema USER_ATTRIBUTES表的ATTRIBUTE列中检索;由于它以JSON格式存储,您可以使用MySQL的JSON函数和运算符来解析其内容。对用户属性的连续更改将与当前值合并,就像使用JSON_MERGE_PATCH()函数一样。
例如:
mysql> CREATE USER 'mary'@'localhost' COMMENT 'This is Mary Smith\'s account';
Query OK, 0 rows affected (0.33 sec)
mysql> ALTER USER 'mary'@'localhost'
-? ATTRIBUTE '{"fname":"Mary", "lname":"Smith"}';
Query OK, 0 rows affected (0.14 sec)
mysql> ALTER USER 'mary'@'localhost'
-? ATTRIBUTE '{"email":"mary.smith@example.com"}';
Query OK, 0 rows affected (0.12 sec)
mysql> SELECT
-> USER,
-> HOST,
-> ATTRIBUTE->>"$.fname" AS 'First Name',
-> ATTRIBUTE->>"$.lname" AS 'Last Name',
-> ATTRIBUTE->>"$.email" AS 'Email',
-> ATTRIBUTE->>"$.comment" AS 'Comment'
-> FROM INFORMATION_SCHEMA.USER_ATTRIBUTES
-> WHERE USER='mary' AND HOST='localhost'\G
*************************** 1. row ***************************
USER: mary
HOST: localhost
First Name: Mary
Last Name: Smith
Email: mary.smith@example.com
Comment: This is Mary Smith's account
1 row in set (0.00 sec)
MySQL 8.0.21在optimizer_switch系统变量中添加了两个新的标志,如下所述:
? prefer_ordering_index标志
默认情况下,当优化器确定使用有序索引可以更快执行带有LIMIT子句的ORDER BY或GROUP BY查询时,MySQL会尝试使用有序索引。然而,在某些情况下,选择不同的优化方式可能会实际表现更好。现在可以通过将prefer_ordering_index标志设置为off来禁用此优化。
该标志的默认值为on。
? subquery_to_derived标志
当将该标志设置为on时,优化器会将符合条件的标量子查询转换为对派生表的连接。例如,查询SELECT * FROM t1 WHERE t1.a > (SELECT COUNT(a) FROM t2)将被重写为SELECT t1.a FROM t1 JOIN ( SELECT COUNT(t2.a) AS c FROM t2 ) AS d WHERE t1.a > d.c。
此优化适用于SELECT、WHERE、JOIN或HAVING子句中的子查询,其中包含一个或多个聚合函数但没有GROUP BY子句,且不是相关的,并且不使用任何非确定性函数。
该优化也适用于作为IN、NOT IN、EXISTS或NOT EXISTS参数的表子查询,且不包含GROUP BY子句。例如,查询SELECT * FROM t1 WHERE t1.b < 0 OR t1.a IN (SELECT t2.a + 1 FROM t2)将被重写为SELECT a, b FROM t1 LEFT JOIN (SELECT DISTINCT 1 AS e1, t2.a AS e2 FROM t2) d ON t1.a + 1 = d.e2 WHERE t1.b < 0 OR d.e1 IS NOT NULL。
从MySQL 8.0.24开始,该优化还可以应用于相关标量子查询,通过对其应用额外的分组,然后在提升的谓词上进行外连接。例如,查询SELECT * FROM t1 WHERE (SELECT a FROM t2 WHERE t2.a=t1.a) > 0可以重写为SELECT t1.* FROM t1 LEFT OUTER JOIN (SELECT a, COUNT(*) AS ct FROM t2 GROUP BY a) AS derived ON t1.a = derived.a WHERE derived.a > 0。MySQL执行基数检查以确保子查询不返回多行(ER_SUBQUERY_NO_1_ROW)。
通常情况下,该优化被禁用,因为在大多数情况下它并不会带来明显的性能优势。该标志默认为off。
从MySQL 8.0.21开始,LOAD XML语句现在支持导入XML中的CDATA节。
从MySQL 8.0.22开始,服务器允许将数据转换为YEAR类型。CAST()和CONVERT()函数都支持单个数字、两位数字和四位数字的YEAR值。对于一位数字和两位数字的值,允许的范围是0-99。四位数字的值必须在1901-2155的范围内。YEAR还可以作为JSON_VALUE()函数的返回类型使用;该函数只支持四位数的年份。
字符串、日期时间和浮点数值都可以转换为YEAR类型。不支持将GEOMETRY值转换为YEAR类型。
从MySQL 8.0.22开始,支持将系统时区的TIMESTAMP列值在检索时转换为UTC DATETIME。使用CAST(value AT TIME ZONE specifier AS DATETIME)语法,其中specifier是[INTERVAL] '+00:00'或'UTC'之一。如果需要,可以通过指定精度高达6位小数的DATETIME值返回的参数来确定精度。在这种构造中,不支持ARRAY关键字。 还支持使用时区偏移插入到表中的TIMESTAMP值。不支持在CONVERT()或任何其他MySQL函数或构造中使用AT TIME ZONE。
从MySQL 8.0.22开始,通过SELECT INTO DUMPFILE和SELECT INTO OUTFILE语句在写入文件时支持定期同步化。可以通过将select_into_disk_sync系统变量设置为ON来启用此功能;写入缓冲区的大小由select_into_buffer_size设置的值确定,默认为131072(217)字节。
此外,可以使用select_into_disk_sync_delay来设置同步到磁盘后的可选延迟时间,默认为无延迟(0毫秒)。
从MySQL 8.0.22开始,准备语句只需准备一次,而不是在每次执行时都要准备。这是在执行PREPARE时完成的。对于存储过程内部的任何语句也是如此;当首次执行存储过程时,语句将被准备一次。
这个改变的一个结果是,准备语句中使用的动态参数的解析方式也按照以下方式进行了更改:
从MySQL 8.0.22开始,服务器在内部将所有RIGHT JOIN实例作为LEFT JOIN处理,消除了在解析时没有完全转换的特殊情况。
MySQL 8.0.22(以及更高版本)实现了针对具有物化派生表的查询的派生条件下推优化。对于诸如SELECT * FROM (SELECT i, j FROM t1) AS dt WHERE i > constant的查询,现在可以在许多情况下将外部WHERE条件下推至派生表,从而得到SELECT * FROM (SELECT i, j FROM t1 WHERE i > constant) AS dt的结果。
在以前,如果派生表被物化但没有合并,MySQL会将整个表进行物化,然后使用WHERE条件对行进行筛选。通过使用派生条件下推优化将WHERE条件移到子查询中,通常可以减少需要处理的行数,从而减少执行查询所需的时间。
当派生表不使用任何聚合或窗口函数时,外部WHERE条件可以直接下推到物化的派生表。当派生表使用GROUP BY但不使用任何窗口函数时,外部WHERE条件可以作为HAVING条件下推到派生表中。当派生表使用窗口函数且外部WHERE条件引用了窗口函数的PARTITION子句中使用的列时,WHERE条件也可以下推到派生表中。
派生条件下推默认情况下是启用的,可以通过optimizer_switch系统变量中的derived_condition_pushdown标志进行确认。这个标志在MySQL 8.0.22中添加,它默认设置为开启。要禁用特定查询的优化,可以使用NO_DERIVED_CONDITION_PUSHDOWN优化器提示(也是在MySQL 8.0.22中添加的)。如果由于设置derived_condition_pushdown为off而禁用了优化,可以使用DERIVED_CONDITION_PUSHDOWN来为特定查询启用优化。
派生条件下推优化不能应用于包含LIMIT子句的派生表。在MySQL 8.0.29之前,当查询包含UNION时也无法使用该优化。从MySQL 8.0.29开始,条件在大多数情况下可以下推到联合查询的两个查询块中。
此外,一个使用子查询的条件无法进行下推,而一个包含在外连接中的派生表作为内部表时,其WHERE条件也无法进行下推。
从MySQL 8.0.22开始,为了允许对MySQL授权表进行并发的DML和DDL操作,之前在MySQL授权表上获取行锁的读操作被执行为非锁定读取。
现在在MySQL授权表上执行的非锁定读取操作包括:
? 通过连接列表和子查询从授权表读取数据的SELECT语句和其他只读语句,包括使用任何事务隔离级别的SELECT ... FOR SHARE语句。
? 使用任何事务隔离级别从授权表中读取数据(通过连接列表或子查询),但不修改它们的DML操作。