美文网首页
MySQL 查询优化

MySQL 查询优化

作者: 偕_2bb8 | 来源:发表于2020-09-25 11:07 被阅读0次

    把查询看作一系列子任务,优化方式:消除一些子任务,减少子任务执行次数,子任务运行得更快。
    响应时间当作重要标准。

    查询的生命周期(大概):从客户端到服务器,服务器解析,生成执行计划并返回结果给客户端。
    查询花费时间在网络,CPU计算,生成统计信息和执行计划,锁等待(互斥等待),底层存储引擎的调用(上下文切换和系统调用),IO操作

    6.2.1 请求不需要的数据:
    1.查询不需要的记录:扫描行数远远大于返回行数。
    2.多表关联时返回全部列
    3.总是取出全部列:select * 总是不太好
    4.重复查询相同的数据,可以建立缓存

    6.2.2
    MySQL最简单的衡量查询开销的三个指标:这三个指标都会记录在MySQL慢日志
    1.响应时间=服务时间+排队时间(等待IO、等待行锁)
    2.扫描行数
    3.返回行数

    EXPLAIN语句的type列反映了访问类型(查询访问方式怎么返回结果)
    EXPALIN内容详解

    /*mysql 8.0 database sakila*/
    mysql> select * from film_actor where film_id =1;
    +----------+---------+---------------------+
    | actor_id | film_id | last_update         |
    +----------+---------+---------------------+
    |        1 |       1 | 2006-02-15 05:05:03 |
    |       10 |       1 | 2006-02-15 05:05:03 |
    |       20 |       1 | 2006-02-15 05:05:03 |
    |       30 |       1 | 2006-02-15 05:05:03 |
    |       40 |       1 | 2006-02-15 05:05:03 |
    |       53 |       1 | 2006-02-15 05:05:03 |
    |      108 |       1 | 2006-02-15 05:05:03 |
    |      162 |       1 | 2006-02-15 05:05:03 |
    |      188 |       1 | 2006-02-15 05:05:03 |
    |      198 |       1 | 2006-02-15 05:05:03 |
    +----------+---------+---------------------+
    10 rows in set (0.06 sec)
    
    mysql> explain select * from film_actor where film_id =1;
    +----+-------------+------------+------------+------+----------------+----------------+---------+-------+------+----------+-------+
    | id | select_type | table      | partitions | type | possible_keys  | key            | key_len | ref   | rows | filtered | Extra |
    +----+-------------+------------+------------+------+----------------+----------------+---------+-------+------+----------+-------+
    |  1 | SIMPLE      | film_actor | NULL       | ref  | idx_fk_film_id | idx_fk_film_id | 2       | const |   10 |   100.00 | NULL  |
    +----+-------------+------------+------------+------+----------------+----------------+---------+-------+------+----------+-------+
    1 row in set, 1 warning (0.00 sec)
    
    mysql> explain select * from film_actor where film_id =1\G
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: film_actor
       partitions: NULL
             type: ref
    possible_keys: idx_fk_film_id
              key: idx_fk_film_id
          key_len: 2
              ref: const
             rows: 10
         filtered: 100.00
            Extra: NULL
    1 row in set, 1 warning (0.00 sec)
    

    删除外键 fk_film_actor_film和索引 idx_fk_film_id

             type: ALL
             rows: 5073
            Extra: Using where
    

    访问类型:全表扫描ALL
    Extra: Using where表示通过where条件来筛选存储引擎返回的记录.

    应用WHERE条件的三种方式,从好到坏:
    1.在索引中使用where,存储引擎层。
    2.使用索引覆盖扫描(Extra: Using index),MySQL服务器层,无须回表查询记录。
    3.Extra: Using where,MySQL服务器层,从数据表读出数据再过滤。

    使用索引减少扫描行数
    mysql> select actor_id,count(*) from film_actor group by actor_id;
    +----------+----------+
    | actor_id | count(*) |
    +----------+----------+
    |        1 |       19 |
    |        2 |       25 |
    |        3 |       22 |
    |      ... |     ...  | 
    200 rows in set (0.01 sec)
    

    如果发现查询需要扫描大量的数据但只返回少量行的优化:
    1.使用索引覆盖扫描
    2.改变库表结构
    3.重写复杂的查询

    6.7 优化特定类型的查询
    6.7.1 count()
    1.统计某列的数量,不统计NULL。count(colmun)
    2.统计行数,统计NULL。count(*),count(1)

    一般查询时,count(1)比count(*)快;
    但主键作为count的参数时,count(主键)比count(1)和count(*)都快;
    MyISAM 的 count() p237。

    相关文章

      网友评论

          本文标题:MySQL 查询优化

          本文链接:https://www.haomeiwen.com/subject/xbrtuktx.html