首页 > 数据库 >MySQL索引优化与SQL调优实战详解

MySQL索引优化与SQL调优实战详解

来源:互联网 2026-07-29 15:18:15

MySQL进阶之路围绕存储引擎(InnoDB支持事务与行锁,MyISAM适合读多写少,Memory基于内存)展开,详解B+树索引结构、聚集索引与二级索引及回表查询,并通过慢查询日志、profile和explain工具进行SQL性能分析,提升数据库优化能力。

一、存储引擎

1.1 MySQL体系结构

把MySQL想象成一座精心设计的四层大楼,每一层都有自己的专属使命,彼此协作处理你的数据请求。下面一层层来看。

一楼接待大厅:连接层

这里是MySQL的“前台接待处”,专门负责:

长期稳定更新的攒劲资源: >>>点此立即查看<<<

  • 为各种客户端(应用程序、命令行工具等)办理入场手续
  • 进行身份安全检查(用户名密码认证)
  • 提供VIP通道(SSL加密连接)
  • 管理接待员团队(线程池),确保不会因为访客太多而手忙脚乱

二楼智慧中心:服务层

这里是MySQL的“大脑”,所有智能决策都在这里发生:

  • 翻译官:把你的SQL语句“翻译”成MySQL能理解的内部指令
  • 策略师:思考最优执行路径(“应该先查哪张表?用哪个索引最快?”)
  • 记忆大师:缓存常用查询结果,下次相同请求直接“秒回”
  • 多功能处理器:内置函数、存储过程都在这里执行

三楼物流仓库:引擎层

这是MySQL最灵活的一层,像是个可更换的物流系统

  • 提供多种“物流方案”(存储引擎)供你选择:
    • InnoDB:像专业搬家公司,事务安全、支持行锁
    • MyISAM:像快递站点,查询速度快但不保证事务
    • Memory:像临时货架,数据放内存,速度极快
  • 每种引擎有自己的“仓储管理方式”(索引实现、数据存储格式)
  • 你可以根据业务需要随时切换引擎,就像根据货物选择快递公司

四楼实体仓库:存储层

这里是实实在在的“数据仓库”:

  • 所有数据最终都存放在这里(硬盘文件系统)
  • 存储着各种“货物清单”:
    • 数据本身和索引(你的核心货物)
    • 操作日志(redolog、undolog,像仓库的进出货记录)
    • 系统日志(错误日志、慢查询日志,像仓库监控记录)

MySQL的独特魅力

和其他数据库相比,MySQL的架构能在多种不同场景中应用并发挥良好作用,关键在于存储引擎——插件式的架构将查询处理其他系统任务数据存储分离开来。这种设计允许根据业务需求灵活选择合适的存储引擎,适应性非常强。

1.2 存储引擎介绍

  1. 建表时指定存储引擎

    CREATE TABLE 表名(
        字段1 字段1类型  [ COMMENT 字段1注释],
        ...
        字段n 字段n类型  [ COMMENT 字段n注释],
    ) ENGINE = INNODB [ COMMENT 表注释];
  2. 查询当前数据库支持的存储引擎

    show engines;

1.3 存储引擎特点

1.3.1 InnoDB

  1. 介绍

    InnoDB是一种兼顾高可靠性和高性能的通用存储引擎,MySQL 5.5之后成为默认引擎。

  2. 特点

    • DML操作遵循ACID模型,支持事务;
    • 行级锁,提高并发访问性能;
    • 支持外键FOREIGN KEY约束,保证数据的完整性和正确性。
  3. 文件

    xxx.ibd:表名对应的表空间文件,存储表结构(frm-早期、sdi-新版)、数据和索引。

  4. 逻辑存储结构

    MySQL索引优化与SQL调优实战详解

    • 表空间:InnoDB存储引擎逻辑结构的最高层,ibd文件就是表空间文件,可包含多个Segment段。
    • 段:表空间由各个段组成,常见的有数据段、索引段、回滚段等。InnoDB自动管理段,无需人为控制,一个段包含多个区。
    • 区:表空间的单元结构,每个区大小为1M。默认页大小为16K,一个区有64个连续页。
    • 页:组成区的最小单元,页也是InnoDB磁盘管理的最小单元,默认大小16KB。为保证连续性,InnoDB每次从磁盘申请4-5个区。
    • 行:InnoDB面向行存储,数据按行存放,每行除定义字段外,还包含两个隐藏字段。

1.3.2 MyISAM

  1. 介绍

    MyISAM是MySQL早期的默认存储引擎。

  2. 特点

    • 不支持事务,不支持外键
    • 支持表锁,不支持行锁
    • 访问速度快
  3. 文件

    xxx.sdi:存储表结构信息

    xxx.MYD: 存储数据

    xxx.MYI: 存储索引

1.3.3 Memory

  1. 介绍

    Memory引擎的表数据存储在内存中,受硬件或断电影响,通常只作为临时表或缓存使用。

  2. 特点

    内存存放,hash索引(默认)

  3. 文件

    xxx.sdi:存储表结构信息

1.3.4 区别及特点

特点InnoDBMyISAMMemory
存储限制64TB
事务安全支持--
锁机制行锁表锁表锁
B+tree索引支持支持支持
Hash索引--支持
全文索引支持(5.6版本之后)支持-
空间使用N/A
内存使用中等
批量插入速度
支持外键支持--

1.4 存储引擎选择

  • InnoDB:MySQL默认引擎,支持事务、外键。如果应用对事务完整性要求高,并发下需要数据一致性,且操作包含大量更新、删除,那么InnoDB是合适的选择。
  • MyISAM:如果应用以读和插入为主,很少更新删除,且对事务完整性、并发性要求不高,MyISAM非常合适。
  • MEMORY:所有数据保存在内存中,访问速度快,适用于临时表及缓存。但表大小有限制,且无法保障数据安全性。

二、索引

2.1 索引概述

2.1.1 介绍

索引(index)是帮助MySQL高效获取数据的有序数据结构。在数据之外,数据库系统维护着满足特定查找算法的数据结构,这些结构以某种方式引用(指向)数据,从而可以在这些结构上实现高级查找算法,这就是索引。

2.1.2 特点

优势劣势
提高数据检索效率,降低数据库IO成本索引列也要占用空间
通过索引列对数据排序,降低排序成本,减少CPU消耗索引提高查询效率,却降低INSERT、UPDATE、DELETE时的效率

2.2 索引结构

2.2.1 概述

索引结果描述
B+Tree索引最常见的索引类型,大部分引擎支持
Hash索引底层用哈希表实现,仅精确匹配有效,不支持范围查询
R-Tree(空间索引)MyISAM引擎的特殊索引,用于地理空间数据,使用较少
Full-text(全文索引)通过倒排索引快速匹配文档,类似Lucene、Solr、ES
索引InnoDBMyISAMMemory
B+tree支持支持支持
Hash索引不支持不支持支持
R-tree索引不支持支持不支持
Full-text5.6之后支持支持不支持

注意:通常所说的索引,若不特别指明,均指B+树结构组织的索引。

2.3 索引分类

2.3.1 索引分类

分类含义特点关键字
主键索引针对表中主键创建的索引默认自动创建,只能有一个PRIMARY
唯一索引避免同一表中某数据列值重复可以有多个UNIQUE
常规索引快速定位特定数据可以有多个
全文索引全文索引查找文本中的关键词,而非比较索引中的值可以有多个FULLTEXT

2.3.2 聚集索引&二级索引

在InnoDB存储引擎中,根据索引的存储形式,可分为两种:

分类含义特点
聚集索引(Clustered Index)将数据与索引放到一起,叶子节点保存行数据必须有,且只有一个
二级索引(Secondary Index)将数据与索引分开存储,叶子节点关联对应主键可以有多个

聚集索引选取规则:

  • 如果存在主键,主键索引就是聚集索引。
  • 如果不存在主键,则使用第一个唯一(UNIQUE)索引作为聚集索引。
  • 如果表没有主键,也没有合适的唯一索引,InnoDB会自动生成一个rowid作为隐藏的聚集索引。

聚集索引和二级索引的具体结构:

MySQL索引优化与SQL调优实战详解

  • 聚集索引的叶子节点下挂的是这一行的数据。
  • 二级索引的叶子节点下挂的是该字段值对应的主键值。

分析一下执行select * from user where name = 'Arm'的查找过程:

  1. 根据name字段到二级索引匹配,找到Arm对应的主键10。
  2. 由于查询返回所有字段,还需根据主键10到聚集索引查找完整记录。
  3. 最终拿到数据返回。

回表查询:先到二级索引查找数据,找到主键值,再到聚集索引根据主键获取数据,这个过程称为回表查询。

2.4 索引语法

  1. 创建索引

    CREATE [ UNIQUE | FULLTEXT ] INDEX 索引名 ON 表名 ( index_col_name,... ) ;
  2. 查看索引

    SHOW INDEX FROM 表名 ;
  3. 删除索引

    DROP INDEX 索引名 ON 表名 ;

    案例演示:

    # 创建系统用户表
    create table tb_user(
        id int primary key auto_increment comment '主键',
        name varchar(50) not null comment '用户名',
        phone varchar(11) not null comment '手机号',
        email varchar(100) comment '邮箱',
        profession varchar(11) comment '专业',
        age tinyint unsigned comment '年龄',
        gender char(1) comment '性别 , 1: 男, 2: 女',
        status char(1) comment '状态',
        createtime datetime comment '创建时间'
    ) comment '系统用户表';
    
    # 插入数据
    insert into tb_user (name, phone, email, profession, age, gender, status, createtime) values 
        ('吕布', '17799990000', 'lvbu666@163.com', '软件工程', 23, '1', '6', '2001-02-02 00:00:00'),
        ('曹操', '17799990001', 'caocao666@qq.com', '通讯工程', 33, '1', '0', '2001-03-05 00:00:00'),
        ('赵云', '17799990002', '17799990@139.com', '英语', 34, '1', '2', '2002-03-02 00:00:00'),
        ('孙悟空', '17799990003', '17799990@sina.com', '工程造价', 54, '1', '0', '2001-07-02 00:00:00'),
        ('花木兰', '17799990004', '19980729@sina.com', '软件工程', 23, '2', '1', '2001-04-22 00:00:00'),
        ('大乔', '17799990005', 'daqiao666@sina.com', '舞蹈', 22, '2', '0', '2001-02-07 00:00:00'),
        ('露娜', '17799990006', 'luna_love@sina.com', '应用数学', 24,'2', '0', '2001-02-08 00:00:00')......;
    
    # 数据准备完毕,完成如下需求:
    # 1. name字段为姓名字段,可能重复,创建索引
    create index idx_user_name on tb_user(name);
    
    # 2. phone字段非空且唯一,创建唯一索引
    create unqiue index idx_user_phone on tb_user(phone);
    
    # 3. 为profession、age、status创建联合索引
    create index idx_user_pro_age_sta on tb_user(profession, age, status);
    
    # 4. 为email建立索引提升查询效率
    create index idx_email on tb_user(email);
    
    # 查看tb_user的所有索引
    show index from tb_user;

2.5 SQL性能分析

2.5.1 SQL执行频率

MySQL客户端连接成功后,通过show [session|global] status可以查看服务器状态信息。以下指令可查看当前数据库的INSERT、UPDATE、DELETE、SELECT访问频次:

# session当前会话,global全局
# Com_delete删除次数,Com_insert插入次数,Com_select查询次数,Com_update更新次数
show global status like 'Com_______';

通过查询执行频次,可以了解当前数据库是以增删改为主还是查询为主,便于后续优化。

2.5.2 慢查询日志

慢查询日志记录所有执行时间超过指定参数(long_query_time,单位秒,默认10秒)的SQL语句日志。

MySQL默认未开启慢查询日志。通过show variabies like 'slow_query_log'查看:

MySQL索引优化与SQL调优实战详解

开启慢查询日志需在MySQL配置文件(/etc/my.cnf)中配置:

# 开启慢日志开关
slow_query_log=1
# 设置慢日志时间2秒,超过2秒视为慢查询
long_query_time=2

配置完后重启MySQL:systemctl restart mysqld,慢日志文件位于/var/lib/mysql/localhost-slow.log。通过慢查询日志可以定位执行效率低的SQL,有针对性地优化。

2.5.3 profile详情

show profiles 能在SQL优化时帮助我们了解时间耗费在哪里。通过select @@ha ve_profiling查看是否支持profile:

MySQL索引优化与SQL调优实战详解

当前MySQL支持profile操作,但开关关闭。可以通过set语句在session/global级别开启:

set profiling = 1;

执行一系列SQL后,通过以下指令查看耗时:

# 查看每一条SQL的耗时基本情况
show profiles;
# 查看指定query_id的SQL语句各个阶段的耗时情况
show profile for query query_id;
# 查看指定query_id的SQL语句CPU使用情况
show profile cpu for query query_id;

查看每一条SQL的耗时情况:

MySQL索引优化与SQL调优实战详解

查看指定SQL各个阶段的耗时情况:

MySQL索引优化与SQL调优实战详解

2.5.4 explain详情

explain或desc命令可以获取MySQL如何执行select语句的信息,包括表如何连接和连接顺序:

# 在select语句前加上关键字explain / desc
explain select 字段列表 from 表名 where 条件;

MySQL索引优化与SQL调优实战详解

字段含义
idselect查询的序列号,表示执行顺序(id相同从上到下,id不同值越大越先执行)
select_typeSELECT类型,常见值:SIMPLE(简单表)、PRIMARY(主查询)、UNION(UNION中的第二个或后面查询)、SUBQUERY(子查询)等
type连接类型,性能由好到差:NULL、system、const、eq_ref、ref、range、index、all
possible_key可能应用在这张表上的索引,一个或多个
key实际使用的索引,为NULL则未使用索引
key_len索引中使用的字节数,值为索引字段最大可能长度,并非实际使用长度,长度越短越好
rowsMySQL认为必须执行查询的行数,在innodb中为估计值
filtered返回结果行数占需读取行数的百分比,值越大越好

2.6 索引使用

2.6.1 最左前缀法则

如果索引了多列(联合索引),需遵守最左前缀法则。即查询从索引的最左列开始,且不跳过中间列。如果跳过某一列,索引将部分失效(后面的字段索引失效)。

在tb_user表中,联合索引idx_pro_age_sta涉及三个字段,顺序为profession、age、status。最左前缀法则要求查询时必须包含profession,否则索引全部失效;且中间不能跳过列,否则跳过列后的字段索引失效。

2.6.2 范围查询

联合索引中,出现范围查询(>、<)时,范围查询右侧的列索引失效。当使用>=或<=时,所有字段都走索引。业务允许的情况下,尽量使用>=或<=这类范围查询。

2.6.3 索引失效情况

2.6.3.1 索引列运算

不要在索引列上进行运算操作,否则索引失效。

# 在tb_user表中,存在idx_phone索引
# 等值匹配查询,索引生效
explain select * from tb_user where phone = '17799990015';
# 函数运算后,索引失效
explain select * from tb_user where substring(phone,10,2) = '15';

2.6.3.2 字符串不加引号

字符串类型字段使用时,不加引号,索引将失效。

2.6.3.3 模糊查询

如果仅仅是尾部模糊匹配,索引不会失效;如果是头部模糊匹配,索引失效。

# 关键字后加%,索引生效
explain select * from tb_user where profession like '软件%';
# 关键字前加%,索引失效
explain select * from tb_user where profession like '%工程';
explain select * from tb_user where profession like '%工%';

2.6.3.3 or连接条件

用or分割的条件,如果or前的列有索引,而后的列没有索引,则涉及的索引都不会被用到。只有当or左右两侧字段都有索引时,索引才会生效。

# 即使id有索引,age没有索引,索引也会失效
explain select * from tb_user where id = 10 or age = 23;

2.6.3.4 数据分布影响

如果MySQL评估使用索引比全表扫描更慢,则不会使用索引。索引适用于索引少量数据,如果通过索引查询返回大批量数据,还不如全表扫描快,此时索引失效。

2.6.4 SQL提示

SQL提示是优化数据库的重要手段,在SQL语句中加入人为提示达到优化目的。

  1. use index:建议MySQL使用某个索引(仅是建议,MySQL内部会再次评估)。

    # 在emp表中,根据软件工程专业查找,使用idx_user_pro索引
    explain select * from tb_user use index(idx_user_pro) where profession = '软件工程';
  2. ignore index:忽略指定的索引。

    # 忽略idx_user_pro索引
    explain select * from tb_user ignore index(idx_user_pro) where profession = '软件工程';
  3. force index:强制使用索引。

    # 强制使用idx_user_pro索引
    explain select * from tb_user force index(idx_user_pro) where profession = '软件工程';

2.6.5 覆盖索引

覆盖索引是指查询使用了索引,且需要返回的列在该索引中已经全部能找到,应减少使用select *。

来看一组SQL的执行计划差别:

explain select id, profession from tb_user where profession = '软件工程' and age = 31 and status = '0' ;
explain select id,profession,age, status from tb_user where profession = '软件工程' and age = 31 and status = '0' ;
explain select id,profession,age, status, name from tb_user where profession = '软件工程' and age = 31 and status = '0' ;
explain select * from tb_user where profession = '软件工程' and age = 31 and status = '0';

执行结果:

MySQL索引优化与SQL调优实战详解

Extra含义
Using where; Using Index查找使用了索引,且数据都在索引列中能找到,无需回表
Using index condition查找使用了索引,但需要回表查询数据

在tb_user表中,联合索引idx_user_pro_age_sta关联了profession、age、status,它是一个二级索引,叶子节点下挂的是主键id。所以当查询返回的数据在id、profession、age、status之中时,直接走二级索引返回数据;如果超出这个范围,需要拿到主键id再去扫描聚集索引获取额外数据,这就是回表。如果一直使用select *,很容易造成回表查询(除非根据主键查询)。

2.6.6 前缀索引

当字段类型为字符串(varchar、text、longtext等),需要索引很长的字符串时,索引会很大,浪费磁盘IO,影响查询效率。此时可以只将字符串的一部分前缀建立索引,大大节约索引空间,提高效率。

  1. 语法
    create index idx_xxxx on table_name(column(n)) ;

例:为tb_user表的email字段建立长度为5的前缀索引:

create index idx_email_5 on tb_user(email(5));
  1. 前缀长度

    根据索引的选择性来决定。选择性是不重复的索引值(基数)与数据表记录总数的比值,越高查询效率越高。唯一索引的选择性是1,性能最好。

2.6.7 单列索引与联合索引

如果表中存在两个字段各自有单列索引,根据这两个字段查询时,会走一个字段的索引,再回表查询。在业务场景中,如果存在多个查询条件,建议建立联合索引,而非单列索引。

2.7 索引设计原则

  1. 针对于数据量较大、查询频繁的表建立索引。
  2. 针对于常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引。
  3. 尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,索引效率越高。
  4. 字符串类型字段长度较长时,可针对字段特点建立前缀索引。
  5. 尽量使用联合索引,减少单列索引。联合索引很多时候可以覆盖索引,节省存储空间,避免回表,提高查询效率。
  6. 控制索引数量,不是越多越好。索引越多,维护索引结构的代价越大,影响增删改效率。
  7. 如果索引列不能存储NULL值,创建表时使用NOT NULL约束。当优化器知道每列是否包含NULL值时,可以更好地决定哪个索引最有效。

三、SQL优化

3.1 插入数据

3.1.1 insert

如果需要一次性往数据库表中插入多条记录,可以从以下三个方面优化:

  1. 方案一:批量插入数据

    insert into tb_user values (1, 'Tom'), (2, 'Cat'), (3, 'Jerry');
  2. 方案二:手动控制事务

    start transaction;
    insert into tb_test values(1,'Tom'),(2,'Cat'),(3,'Jerry');
    insert into tb_test values(4,'Tom'),(5,'Cat'),(6,'Jerry');
    insert into tb_test values(7,'Tom'),(8,'Cat'),(9,'Jerry');
    commit;
  3. 方案三:主键顺序插入,性能高于乱序插入

    # 主键乱序插入 : 8 1 9 21 88 2 4 15 89 5 7 3
    # 主键顺序插入 : 1 2 3 4 5 7 8 9 15 21 88 89

3.1.2 大批量插入数据

如果一次性需要插入大批量数据(比如几百万条),使用insert语句性能较低,此时可以使用MySQL数据库提供的load指令:

# 客户端连接服务端时,加上参数 --local-infile
mysql --local-infile -u root -p
# 设置全局参数local_infile为1,开启从本地加载文件导入数据的开关
set global local_infile = 1;
# 执行load指令将准备好的数据加载到表结构中
load data local infile '/root/sql1.log' into table tb_user fields terminated by ',' lines terminated by 'n' ;

3.2 主键优化

主键顺序插入性能高于乱序插入的原因:

  1. 数据组织方式

    在InnoDB存储引擎中,表数据根据主键顺序组织存放,这种表称为索引组织表(index organized table IOT)。行数据存储在聚集索引的叶子节点上。

    数据行记录在逻辑结构page页中,每个页大小固定,默认16K。如果插入的数据行在该页存储不下,会存储到下一个页,页与页之间通过指针连接。

    MySQL索引优化与SQL调优实战详解

    MySQL索引优化与SQL调优实战详解

  2. 页分裂

    页可以为空、填充一半或100%。每个页包含2-N行数据(如果一行数据过大,会行溢出),根据主键排列。

    • 主键顺序插入,将行数据依次写入页中,写满后申请第二个页,页与页通过指针连接。
    • 主键乱序插入,当插入数据需要插入到两页中间时,会申请一个新页,将原来两页中较小页的数据分担存放,再插入新数据。

    MySQL索引优化与SQL调优实战详解

  3. 页合并

    删除数据时,记录并未物理删除,只是标记(flaged)为删除,空间允许被其他记录声明使用。当页中删除的记录达到MERGE_THRESHOLD(合并页阈值,默认页的50%),InnoDB会寻找最近的页(前或后)看是否可以将两个页合并以优化空间使用。

  4. 索引设计原则

    • 满足业务需求时,尽量降低主键的长度
    • 插入数据时,尽量选择顺序插入,使用AUTO_INCREMENT自增主键
    • 尽量不要使用UUID或其他自然主键(如身份证号)
    • 业务操作时,避免对主键修改

3.3 order by优化

MySQL的排序有两种方式:

Using filesort:通过表的索引全表扫描读取满足条件的数据行,然后在排序缓冲区sortbuffer中完成排序。所有不是通过索引直接返回排序结果的都叫FileSort排序。

Using index:通过有序索引顺序扫描直接返回有序数据,不需要额外排序,操作效率高。

显然Using index性能高,Using filesort性能低,优化时尽量优化为Using index。

order by优化原则:

  • 根据排序字段建立合适的索引,多字段排序时遵循最左前缀法则
  • 尽量使用覆盖索引
  • 多字段排序,一个升序一个降序时,注意联合索引创建时的规则(ASC/DESC)。
  • 如果不可避免出现filesort,大数据量排序时可适当增大排序缓冲区大小sort_buffer_size(默认256k)。

3.4 group by优化

在分组操作中,通过以下两点优化提升性能:

  • 在分组操作时,通过建立索引提高效率。
  • 分组操作时,索引的使用也满足最左前缀法则

3.5 limit优化

数据量大时,limit分页查询越往后效率越低。因为执行limit (2000000,10)时,MySQL需要排序前2000010条记录,仅返回2000000-2000010的记录,其他丢弃,查询排序代价非常大。

优化思路:一般分页查询时,通过创建覆盖索引能较好提高性能,可以通过覆盖索引加子查询形式进行优化。

3.6 count优化

3.6.1 概述

数据量大时,执行count操作非常耗时。

  • MyISAM引擎把表的总行数存在磁盘上,执行count(*)时直接返回,效率很高;但带条件的count也会慢。
  • InnoDB引擎执行count(*)时,需要把数据一行一行读出来累加计数。

要大幅度提升InnoDB表的count效率,主要优化思路:自己计数(可以借助redis,但带条件的count仍然复杂)。

3.6.2 count用法

count用法含义
count(主键)InnoDB遍历整张表,取出主键id值返回给服务层,服务层直接按行累加
count(字段)没有not null约束:遍历整张表取出字段值,服务层判断是否为null,不为null则累加;有not null约束:直接按行累加
count(数字)InnoDB遍历整张表但不取值,服务层对每一行放一个数字“1”直接累加
count(*)InnoDB专门做了优化,不取值,服务层直接按行累加

按照效率排序:count(字段) < count(主键id) < count(1) ≈ count(*),所以尽量使用count(*)。

总结

侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述

热游推荐

更多
湘ICP备2026025700号-3 湘公网安备 43070302000280号
All Rights Reserved
本站为非盈利网站,不接受任何广告。本站所有软件,都由网友
上传,如有侵犯你的版权,请发邮件给xiayx666@163.com
抵制不良色情、反动、暴力游戏。注意自我保护,谨防受骗上当。
适度游戏益脑,沉迷游戏伤身。合理安排时间,享受健康生活。