MySQL调优01 深碍√TFBOYSˉ_ 2021-09-25 10:18 241阅读 0赞 ### 文章目录 ### * 资料转载说明 * 1 B树 * * 1.1 B树的概念以及特性 * 1.2 5叉树举例说明B树的特性 * 2 B+树 * * 2.1 B+树和B树的区别 * 2.2 B+树示意图 * 2.3 B+树的优势 * 2.4 MySQL中的B+树 * 3 索引分类 * 4 索引的基本语法 * * 4.1 创建索引 * 4.2 查看索引 * 4.3 删除索引 * 4.4 ALTER命令 * 5 MySQL体系结构(作为了解) * 6 存储引擎 * * 6.1存储引擎概述 * 6.2存储引擎语法 * 7 存储引擎InnoDB与存储引擎MyISAM的区别 * 8 InnoDB存储引擎 * * 8.1 InnoDB存储引擎的特性 * * 8.1.1 事务控制 * 8.1.2 外键约束 * 8.1.3 锁 * 9 MyISAM引擎的特性 * 10 存储引擎的选择 * 11 优化SQL * * 11.1 查看SQL执行频率 * 11.2 定位低效率执行SQL * 11.3 explain分析执行计划 * * 11.3.1 explain的id * 11.3.2 explain的select\_type * 11.3.3 explain的table * 11.3.4 explain的type * 11.3.5 explain之key * 11.3.6 explain之rows * 11.3.7 explain之extra * 11.4 show profile分析SQL * 11.5 trace分析优化器执行计划 # 资料转载说明 # 本博客中所有截图知识点均来自[https://www.bilibili.com/video/BV1UQ4y1P7Xr?p=1][https_www.bilibili.com_video_BV1UQ4y1P7Xr_p_1] # 1 B树 # ## 1.1 B树的概念以及特性 ## B树又叫多路平衡搜索树,一棵m叉的B树特性如下: * 树中每个节点最多包含m个孩子。 * 除根节点与叶子节点外,每个节点至少有\[ceil(m/2)\]个孩子。 * 若根节点不是叶子节点,则至少有两个孩子。 * 所有的叶子节点都在同一层。 * 每个非叶子节点由n个key与n+1个指针组成,其中\[ceil(m/2)-1\]<= n <= m-1 ## 1.2 5叉树举例说明B树的特性 ## 5叉树,根据特性**每个非叶子节点由n个key与n+1个指针组成,其中\[ceil(m/2)-1\]<= n <= m-1** 算出 2<= n <=4。当n>4时,中间节点分裂到父节点,两边节点分裂。 插入 C N G A H E K Q M F W L T Z D P R X Y S数据为例 演变过程如下: (1)插入前4个字母C N G A ![在这里插入图片描述][20210603230913113.png_pic_center] (2)插入H,n>4,中间元素G字母向上分裂到新的节点 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center] (3)插入E K Q不需要分裂 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 1] (4)插入M,中间元素M字母向上分裂到父节点G ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 2] (5)插入F W L T不需要分裂 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 3] (6)插入Z,中间元素T向上分裂到父节点中 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 4] (7)插入D,中间元素D想上分裂到父节点中。然后插入P,R,X,Y不需要分裂 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 5] (8)最后插入S,NPQR节点>5,中间节点Q向上分裂,但分裂后父节点DGMT的n>5,中间节点M向上分裂 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 6] 到此,该B树就已经构建完成了,B树和二叉树相比,查询数据的效率更高,因为对于相同的数据量来说,B树的层级结构比二叉树小,因此搜索速度快。 # 2 B+树 # ## 2.1 B+树和B树的区别 ## B+树为B数的变种,B+树和B树的区别为: * n叉B+树最多含有n个key,而B树最多含有n-1个key * B+树的叶子节点保存所有的key信息,依key大小顺序排列 * 所有的非叶子节点都可以看作是key的索引部分 ## 2.2 B+树示意图 ## ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 7] ## 2.3 B+树的优势 ## 由于B+树只有叶子节点保存key信息,查询任何key都要从root走到叶子,所以B+树的查询效率更加稳定。 ## 2.4 MySQL中的B+树 ## MySQL索引数据结构对经典的B+数进行了优化。在原B+树的基础上,增加一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的B+树,提高区间访问的性能。 MySQL中的B+树索引结构示意图: ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 8] # 3 索引分类 # * 单值索引(也叫单列索引):即一个索引只包含单个列,一个表可以有多个单值索引 * 唯一索引:索引列的值必须唯一,但允许有空值 * 复合索引:即一个索引包含多个列 # 4 索引的基本语法 # ## 4.1 创建索引 ## CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [USING index_type] ON tbl_name(index_col_name,...) index_col_name:column_name[(length)][ASC | DESC] 语法解析: create unique唯一/fulltext全文/spatial(一般不写,为普通索引) index 索引名 \[使用的索引类型(如果没有指定,默认是B+树)\] on 表名(列名1,列名2,…) 注意:在MySQL中,如果当前字段是主键,默认有一个主键索引 示例:为city表中的city\_name字段创建索引 create index idx_city_name on city(city_name); ## 4.2 查看索引 ## show index from table_name; 语法解析: show index from 表名; ## 4.3 删除索引 ## drop index index_name on tbl_name; 语法解析: drop index 索引名 on 表名; ## 4.4 ALTER命令 ## alter table tb_name add primary key(column_list); 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为null alter table tb_name add unique index_name(column_list); 这条语句创建索引的值必须是唯一的(除了NULL外,NULL可能会出现多次) alter table tb_name add index_name(column_list); 添加普通索引,索引值可以出现多次 alter table tb_name add fulltext index_name(column_list); 该语句指定了索引为FULLTEXT,用于全文索引 # 5 MySQL体系结构(作为了解) # MySQL Server由以下组成: Connection Pool 连接池组件 Management Service & Utilities : 管理服务和工具组件 SQL interface : SQL接口组件 Parser:查询分析器组件 Optimizer:优化器组件 Caches & Buffers: 缓冲池组件 Pluggable Storage Engines : 存储引擎 File System: 文件系统 (1)连接层: 最上层是一些客户端和链接服务,包含本地sock 通信和大多数基于客户端/服务端工具实现的类似于TCP/IP的通信。主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程池的概念,为通过认证安全接入的客户端提供线程。同样在该层上可以实现基于SSL的安全链接。服务器也会为安全接入的每个客户端验证它所具有的操作权限。 (2)服务层: 第二层架构主要完成大多数的核心服务功能,如SQL接口,并完成缓存的查询,SQL的分析和优化,部分内置函数的执行。所有跨存储引擎的功能也在这一层实现,如过程、函数等。在该层,服务器会解析查询并创建相应的内部解析树,并对其完成相应的优化如确定表的查询的顺序,是否利用索引等,最后生成响应的执行操作。如果是select语句,服务器还会查询内部的缓存,如果缓存空间足够大,这样在解决大量读操作的环境中能够很好的提升系统的性能。 (3)引擎层: 存储引擎层,存储引擎真正的负责了MySQL中数据的存储和提取,服务器通过API和存储引擎进行通信。不同的存储引擎具有不同的功能,这样我们可以根据自己的需要,来选取合适的存储引擎 (4)存储层 数据存储层,主要是将数据存储在文件系统之上,并完成与存储引擎的交互。 # 6 存储引擎 # ## 6.1存储引擎概述 ## 存储引擎就是存储数据,建立索引,更新查询数据等等技术的实现方式。存储引擎是基于表的,而不是基于库的。所以存储引擎也可被称为表类型。 ## 6.2存储引擎语法 ## 查看MySQL支持的所有存储引擎 show engines; 查看MySQL默认的存储引擎 show variables like '%storage_engine%'; MySQL 5.5之前默认的存储引擎是MyISAM 5.5之后默认的存储引擎是InnoDB # 7 存储引擎InnoDB与存储引擎MyISAM的区别 # * 事务安全:InnoDB支持,MyISAM不支持 * 锁机制:InnoDB是行锁(适合高并发),MyISAM是表锁 * 是否支持外键:InnoDB支持。MyISAM不支持 # 8 InnoDB存储引擎 # InnoDB存储引擎设计MySQL的默认存储引擎。InnoDB存储引擎提供了具有提交、回滚、崩溃恢复能力的事务安全。但是对比MyISAM的存储引擎,InnoDB写的处理效率差一些,并且会占用更多的磁盘空间以保留数据和索引。 ## 8.1 InnoDB存储引擎的特性 ## ### 8.1.1 事务控制 ### 示例:同时打开两个CMD窗口,两个窗口中使用同一个表,一个窗口中执行insert语句,向表中插入数据;另外一个窗口查询表中的所有数据。 此时查询到的数据是空的,因为执行insert语句的窗口并没有执行commit语句,没有提交事务 ### 8.1.2 外键约束 ### MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候,也会自动的创建对应的索引。 创建表 create table country_innodb( country_id int NOT NULL AUTO_INCREMENT, country_name varchar(100) NOT NULL, primary key (country_id) )ENGINE=InnoDB DEFAULT CHARSET=utf8; create table city_innodb( city_id int NOT NULL AUTO_INCREMENT, city_name varchar(50) NOT NULL, country_id int NOT NULL, primary key(city_id), key idx_fk_country_id(country_id), CONSTRAINT `fk_city_country` FOREIGN KEY(country_id) REFERENCES country_innodb(country_id) ON DELETE RESTRICT ON UPDATE CASCADE )ENGINE=InnoDB DEFAULT CHARSET=utf8; 解释: ON DELETE RESTRICT 删除主表数据时,如果有关联记录,则不删除 ON UPDATE CASCADE 更新主表时,如果子表有关联记录,更新子表记录 向表中插入数据 insert into country_innodb values(null,'china'),(null,'America'),(null,'Japan'); insert into city_innodb values(null,'Xian',1),(null,'NewYork',2),(null,'Beijing',1); 查看表结构 desc city_innodb; desc country_innodb; 在创建索引时,可以指定在删除、更新父表时,对子表进行的相应操作,包括RESTRICT、CASCADE、SET NULL 和 NO ACTION。 RESTRICT和NO ACTION相同,是指限制在子表有关联记录的情况下,父表不能更新; CASCADE表示父表在更新或者删除时,更新或者删除子表对应的记录; SET NULL则表示父表在更新或者删除的时候,子表的对应字段被SET NULL InnoDB存储表和索引有以下两种方式: (1)使用共享表空间存储,这种方式创建的表的表结构保存在.frm文件中,数据和索引保存在innodb\_data\_home\_dir和innodb\_data\_file\_path定义的表空间中,可以是多个文件。 (2)使用多表空间存储,这种方式创建的表的表结构仍然存在.frm文件中,但是每个表的数据和索引单独保存在.ibd中 ### 8.1.3 锁 ### # 9 MyISAM引擎的特性 # MyISAM不支持事务、也不支持外键,其优势是访问的速度快,对事务的完整性没有要求或者以SELECT、INSERT为主的应用基本上都可以使用这个引擎来创建表。有以下两个比较重要的特点: (1)不支持事务 (2)文件存储方式 .frm(存储表定义) .MYD(MYData,存储数据) .MYI(MYIndex,存储索引) # 10 存储引擎的选择 # 在选择存储引擎时,应该根据应用系统的特点选择合适的存储引擎,对于复杂的应用系统,还可以根据实际情况选择多种存储引擎进行组合。 **InnoDB**:是MySQL的默认存储引擎,用于事务处理应用程序,支持外键。如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询事件,还包含很多的更新、删除操作,那么InnoDB存储引擎是比较合适的选择。InnoDB存储引擎除了有效的降低由于删除和更新导致的锁定,还可以确保事务的完整提交和回滚,对于类似于计费系统或者财务系统等对数据准确性要求比较高的系统,InnoDB是最合适的选择 **MyISAM**:如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性、并发性要求不是很高,那么选择这个存储引擎是非常合适的。 # 11 优化SQL # ## 11.1 查看SQL执行频率 ## 命令`show[session|global]status`可以提供服务器状态信息。 session(当前连接) global(自数据库上次启动至今) 默认是session 显示当前session中所有统计参数的值 查看整个数据库的 show status like 'Com_______'; 查看Innodb存储引擎的 show global status like 'Innodb_rows_%'; ## 11.2 定位低效率执行SQL ## 定位执行效率较低的SQL语句有两种方式 1. 慢查询日志 2. show processlist:慢查询日志在查询结束以后才记录,所以在应用反映执行效率出现问题的时候查询慢查询日志并不能定位问题。可以使用show processlist命令查看当前MySQL在进行的线程,包括线程的状态、是否锁表等,可以实时地查看SQL的执行情况,同时对一些锁表操作进行优化。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 9] (1)id列,用户登录MySQL时,系统分配的"connection\_id",可以使用函数connection\_id()查看 (2)user列,显示当前用户,如果不是root,这个命令就只显示用户权限范围的SQL语句 (3)host列,显示这个语句是从哪个ip的端口上发的,可以用来跟踪出现问题语句的用户 (4)db列,显示这个进程目前连接的是哪个数据库 (5)command列,显示当前连接的执行的命令,一般取值为休眠(sleep),查询(query),连接(connect)等 (6)time列,显示这个状态持续的时间,单位是秒 (7)state列,显示使用当前连接的SQL语句的状态,很重要的列,state描述的是语句执行中的某一个状态。一个SQL语句,以查询伪例,可能需要经过copying to tmp table 、 sorting result 、 sending data等状态才可以完成 (8)info列,显示这个SQL语句,是判断问题语句的一个重要依据 ## 11.3 explain分析执行计划 ## 通过explain或者desc 命令获取MySQL如何执行select语句的信息,包括select语句执行过程中表如何连接和连接的顺序。 ![在这里插入图片描述][20210606222901595.png_pic_center] ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 10] ### 11.3.1 explain的id ### id字段是select查询的序列号,是一组数字,表示的是查询中执行select子句或者是操作表的顺序。id情况有3种: (1)id相同表示加载表的顺序是从上到下。 (2)id不同id值越大,优先级越高,越先被执行。 (3)id有相同,也有不同,同时存在。id相同的可以认为是一组,从上而下顺序执行;在所有的组中,id的值越大,优先级越高,越先执行。 ### 11.3.2 explain的select\_type ### 表示select的类型,常见的取值:(从上到下,效率越来越低) ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 11] ### 11.3.3 explain的table ### 展示这一行的数据是关于哪一张表的 ### 11.3.4 explain的type ### type显示的是访问类型,是较为重要的一个指标。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 12] 结果值从最好到最坏依次是: NULL > system > const > eq\_ref > ref > fulltext > ref\_or\_null > index\_merge > unique\_subquery > index\_subquery > range > index > ALL system > const > eq\_ref > range > index > ALL **一般来说,我们需要保证查询至少达到range级别,最好达到ref** ### 11.3.5 explain之key ### possible\_keys:显示可能应用在这张表的索引,一个或多个。 key:实际使用的索引,如果为NULL,则没有使用索引。 key\_len:表示索引中使用的字节数,该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下,长度越短越好 ### 11.3.6 explain之rows ### 扫描行的数量 ### 11.3.7 explain之extra ### 其他的额外的执行计划信息,在该列展示。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 13] ## 11.4 show profile分析SQL ## -- 查看当前MySQL是否支持profile select @@have_profiling; -- 查看profiling的状态(0为关闭,1为开启) select @@profiling; -- 开启profiling开关 set profiling = 1; -- 查看执行的所有指令及其耗时 show profile; --查看某条指令的各个阶段的耗时 show profile for query 编号; starting 开启 checking permissions 校验权限 Opening table 打开表 init 初始化 System lock 系统锁 optimizing 优化器 statistics 统计 preparing 准备 executing 执行 Sending data 发送数据 end 结束 query end 查询结束 closing tables 关闭表 freeing items cleaning up Sending data 状态表示MySQL线程开始访问数据行并把结果返回给客户端,而不仅仅是返回给客户端。由于在Sending data 状态下,MySQL线程往往需要做大量的磁盘读取操作,所以经常是整个查询中耗时最长的状态 ## 11.5 trace分析优化器执行计划 ## MySQL5.6提供了对SQL的跟踪trace,通过trace文件能够进一步了解为什么优化器选择A计划,而不是选择B计划。 打开trace,设置格式为JSON,并设置trace最大能够使用的内存大小,避免解析过程中因为默认内存过小而不能完整显示。 set optimizer_trace="enabled=on",end_markers_in_json=on; set optimizer_trace_max_mem_size=1000000; [https_www.bilibili.com_video_BV1UQ4y1P7Xr_p_1]: https://www.bilibili.com/video/BV1UQ4y1P7Xr?p=1 [20210603230913113.png_pic_center]: /images/20210923/1cac810181bf4a01b596a46dec45efd0.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center]: /images/20210923/c2d2b64c7250440eaf7fa67c6857c0ce.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 1]: /images/20210923/5c0b72eabf4f4f3d91fffb6f6b18f782.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 2]: /images/20210923/a9ffa2907f8e4754a2d76f3a45b7c214.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 3]: /images/20210923/14a18ac232e44f8b9ea3dc9ae205d876.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 4]: /images/20210923/2da56eebafe6463eac6dbd765c50b7a4.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 5]: /images/20210923/75b584da75984311b515a3455d070de5.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 6]: /images/20210923/2f8ec9c19ace43708bff050da4a7651d.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 7]: /images/20210923/78e1ebb0b32045acaf1e64dd1078ec23.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 8]: /images/20210923/6ca965fe284f4649b55f590732dcd1dc.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 9]: /images/20210923/e4e31e2b196646e6b750786422d716a9.png [20210606222901595.png_pic_center]: /images/20210923/fd265243eb9642ec9693f3c3a303e00b.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 10]: /images/20210923/64cfd7b0cdf6463a8b46cef29ac5ef38.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 11]: /images/20210923/069a4c1c749845df8cee098e089e37b0.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 12]: /images/20210923/2facdf14fc6347ba9834da060f1458e6.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5cGVydGV4dDEyMw_size_16_color_FFFFFF_t_70_pic_center 13]: /images/20210923/c2b0c0d74b5a4da6a2d46269f7f62172.png
还没有评论,来说两句吧...