学习目标:

1.会分析SQL的执行计划

2.能优化数据访问 3.能从子查询优化、Limit查询优化及优化GROUP BY子句等方面分析查询优化的策略 学习内容:

画板

一、思考问题:如何优化数据访问?

数据查询是应用系统中最频繁的操作,当要访问的数据量很大时,查询不可避免地需要筛选大量的数据,造成查询性能低下。
  • 影响查询性能的主要原因?

向数据库请求不需要的数据

1)查询不需要的记录

2)多表关联时返回全部列

3)总是取出全部列

查询的开销

1)响应时间

(2)扫描的行数和返回的行数

6.4 编写高效的数据查询 - 图2

二、优化数据访问

实例:查询会员蔡静购买的所有商品信息。

方案一:
  1. SELECT *
  2. FROM users join cart USING(uid)
  3. join goods USING(gid)
  4. WHERE uname = '蔡静' ;
方案二:
  1. SELECT goods.*
  2. FROM users join cart USING(uid)
  3. join goods USING(gid)
  4. WHERE uname = '蔡静' ;

问:哪种方案执行效率更高?

方法二,按需取材

三、SQL的执行计划

要编写高效的查询语句,需要了解查询语句执行情况,找出查询语句执行的瓶颈,从而优化查询。

EXPLAIN | DESCRIBE | DESC [ANALYZE] SELECT语句 ; 说明:EXPLAIN | DESCRIBE | DESC:任选其一可以分析SELECT语句的执行情况,并且能够分析出所查询表的相关特征。DESCRIBE多用于查看表结构,这里建议使用EXPLAIN。 · ANALYZE:该关键字为MySQL8.0新增。向用户详细显示查询语句执行过程中,查询的具体时间花费及原因。

学习提示:执行该语句,可以分析EXPLAIN后SELECT语句的执行情况,并且能够分析出所查询表的一些特征。

实例:使用EXPLAIN语句分析查询users_bg表的执行计划

  1. EXPLAIN SELECT * FROM users_bg WHERE card = 'HS395964JA39';

查询分析器的查询类型:

6.4 编写高效的数据查询 - 图3 分析查询执行的精确时间
  1. EXPLAIN SELECT g.gname,g.gprice,c.cnum # 查询必要列
  2. FROM users u
  3. NATURAL JOIN cart c
  4. NATURAL JOIN goods g
  5. WHERE uname = '段湘林';

6.4 编写高效的数据查询 - 图4

四、优化查询

1.添加索引优化查询

实例:为表users_bg中card列建立索引,并再次查看执行计划和执行时间。

  1. -- 删除索引
  2. DROP INDEX idx_name on user_bg;
  3. -- 创建索引
  4. CREATE INDEX idx_name on user_bg(uname);
  5. -- 没有uname索引时,时间: 0.071s
  6. SELECT *
  7. FROM user_bg
  8. WHERE uname = '段湘林';
  9. -- 使用索引,再次执行查询 时间: 0.001s
  10. SELECT *
  11. FROM user_bg
  12. WHERE uname = '段湘林';

结论:在大数据查询时,有索引时,查询效率大大高于无索引的查询。

2.Limit分页优化查询

影响查询速度的原因除是否添加索引外,获取记录的页数也会影响查询性能。当要进行分页操作时,通常会使用LIMIT子句实现。但是当分页操作要求偏移量非常大的时候,代价就非常高。

实例:查询users_bg表中第20001-20010行共10行数据。 方法一:

— 使用limit子句分页

  1. SELECT * FROM user_bg -- 时间: 0.031s
  2. LIMIT 20000,10;
方法二:
  1. SELECT * -- 时间: 0.002s
  2. FROM user_bg
  3. WHERE uid > 20000
  4. LIMIT 10;
3.覆盖索引优化查询

SELECT查询的数据列从索引中就能够取得,不必读取数据行。即,查询列要被所建立的索引覆盖,索引的字段不仅仅包含查询的列,还包含查询条件、排序等。

实例:查询users_bg表中的id和card列,并按card列升序排列,返回500001-500010之间的行。
  1. SELECT id, card FROM users_bg WHERE id > 500000 ORDER BY card LIMIT 10 ;

优化方案:

实例:查询users_bg表中的card,age列,并按card列排序,返回1000行数据。
  1. SELECT card, age FROM users_bg ORDER BY card LIMIT 1000 ;
优化方案:

五、实践任务

1)创建索引、查看索引和维护索引。

2)创建视图、管理和维护视图以及使用可更新视图。

3)写出各种高效数据查询的方法。

实践内容

1)使用Navicat图形工具在onlinedb.goodstype表的tName列上创建一个为IX_tName的普通索引名。

2)使用SQL语句在onlinedb.goods表的gdCodegdName列上创建一个名为IX_gdCN的复合索引。

3)分别使用SHOW CREATE TABLE命令和SHOW INDEX FROM/SHOW KEYS FROM命令查看(2)中所创建的索引IX_gdCN的相关信息。

(4)使用SQL语句删除(1)和(2)创建的索引。

课堂小结:

  1. 优化查询的三种方法:

(1)建立条件索引优化查询;(2)充分使用主键索引作为筛选条件,优化分页查询;(3)覆盖索引优化查询,要注意第一索引没有使用时,其他列索引无效。

  1. 在不常更新的列上建索引更加有效,索引不宜多建,会影响数据维护的效率。