目标:MySQL8 新特性
分析:
详解:
第一部分 默认编码utf8mb4
从 MySQL8 开始,数据库的缺省编码将改为 utf8mb4,这个编码包含了所有 emoji 字符。以后不用担心忘了修改数据库编码了。
第二部分 配置项持久化到配置文件
经常会碰到这种情况,服务启动后需要调整参数,线上服务器又不能重启,如果哪一天服务器重启,可能又忘记设置参数。真是头疼呢。为什么不同步到配置文件呢,这样多好啊。MySQL8 新增了 SET PERSIST 命令,解决了这个头疼的运维问题。
例如,SET PERSIST innodb_strict_mode = 0,会写入 /path/data/mysqld-auto.cnf 文件中,下次启动时会读取该文件,用其中的配置来覆盖缺省的配置文件。
mysqld-auto.cnf文件内容示例:
{ "Version" : 1 , "mysql_server" : { "innodb_strict_mode" : { "Value" : "OFF" , "Metadata" : { "Timestamp" : 1642088962268745 , "User" : "root" , "Host" : "localhost" } } } }
第三部分 索引不可见
有没有碰到这种问题,想测试索引有没有用,或者对比索引,删除重建索引很麻烦,而且在表数据量大的时候删除重建索引根本不可行。MySQL8 新增了隐藏索引的功能,解决了这个问题。
ALTER TABLE table ALTER INDEX idx INVISIBLE; 设置索引idx不可见,就是不可用。
ALTER TABLE table ALTER INDEX idx VISIBLE; 设置索引idx可见,可能会使用。
第四部分 通用表达式CTE (Common Table Expressions)
这个功能其他的数据库如PostgreSQL,Oracle都有,这个是 MySQL8 的一个新增功能。
1、为什么用CTE
- 情况一:同一查询如果多次使用同一派生表,MySQL是不知道这是同一个派生表的,就会多次计算,这样导致性能下降。
- 情况二:同一查询如果使用多个派生表,派生表相互之间不能互相引用。如果要使用就会嵌套,不仅sql复杂,而且多次计算派生表。
- 情况三:递归。
2、CTE语法
WITH [RECURSIVE]
cte_name [(col_name [, col_name] ...)] AS (subquery)
[, cte_name [(col_name [, col_name] ...)] AS (subquery)] ...
递归 CTE 具有以下结构
- WITH RECURSIVE开头
- 递归 CTE 子查询有两部分,由 UNION [ALL] or分隔 UNION DISTINCT
SELECT ... -- return initial row set
UNION ALL
SELECT ... -- return additional row sets
第一个[SELECT]为 CTE 生成一个或多个初始行,并且不引用 CTE 名称。第二个[SELECT] 通过在其FROM子句中引用 CTE 名称来产生额外的行和递归。当这部分不产生新行时,递归结束。因此,递归 CTE 由非递归 [SELECT]部分和递归[SELECT]部分组成。
3、非递归
WITH cte (col1, col2) AS
(
SELECT 1, 2
UNION ALL
SELECT 3, 4
)
SELECT col1, col2 FROM cte;
4、递归
WITH RECURSIVE cte (n) AS
(
SELECT 1
UNION ALL
SELECT n + 1 FROM cte WHERE n < 5
)
SELECT * FROM cte;
对于递归 CTE,递归 [SELECT]部分包含终止递归的条件很重要。作为一种防止失控递归 CTE 的开发技术,您可以通过限制执行时间来强制终止:
- [
cte_max_recursion_depth] 系统变量强制限制 CTE 的递归级别数 。服务器终止执行任何递归级别多于此变量值的 CTE。 - 系统变量为在当前会话中执行的语句 强制[
max_execution_time] 执行超时 。[SELECT] - 优化器提示对其出现的语句 强制[
MAX_EXECUTION_TIME] 执行每个查询的执行超时。[SELECT]
5、参考
第五部分 窗口函数
这个功能其他的数据库如PostgreSQL,Oracle都有,这个是 MySQL8 的一个新增功能。