• 查询优化


    查询慢的原因

    • 网络
    • CPU
    • IO
    • 上下文切换
    • 系统调用
    • 生成统计信息
    • 锁等待时间

    优化数据访问

    减少访问数据量的方式进行优化

    • 确认应用程序是否在检索大量超过需要的数据
    • 确认mysql服务器层是否在分析大量超过需要的数据行

    是否向数据库请求了不需要的数据

    • 查询不需要的记录
    • 多表关联时返回全部
    • 总是取出全部
    • 重复查询相同的数据

    执行过程的优化

    查询缓存(MySQL8之后移除)

    LRU淘汰策略

    JoinBuffer(待更新)

    排序优化

    两次传输排序

    • 第一次数据读取是将需要排序的字段读取出来,然后进行排序,第二次是将排好序的结果按照需要去读取数据行
    • 这种方式效率比较低,原因是第二次读取数据的时候因为已经排好序
    • 需要去读取所有记录而此时更多的是随机IO读取数据成本会比较高
    • 两次传输的优势,在排序的时候存储尽可能少的数据,让排序缓冲区可以尽可能多的容纳行数来进行排序操作

    单次传输排序

    • 先读取查询所需要的所有列,然后再根据给定列进行排序,最后直接返回排序结果
    • 此方式只需要一次顺序IO读取所有的数据,而无须任何的随机IO
    • 问题在于查询的列特别多的时候,会占用大量的存储空间,无法存储大量的数据

    排序的列的总大小超过 max_length_for_sort_data 定义的字节,mysql会选择双次排序,反之使用单次排序

    优化特定类型的查询

    优化count()查询

    • count(1),count(*),count(col) 效率是一样的
    • myisam的count函数,没有任何where条件的count(*)才是比较快的
    • 使用近似值(hyperloglog)
    • 复杂的优化,在实际操作的时候可以考虑使用索引覆盖扫描,或者增加汇总表,或者增加外部缓存系统

    优化关联查询

    • 确保on或者using子句中的列上有索引,在创建索引的时候就要考虑到关联的顺序
    • 确保任何的group by和order by中的表达式只涉及到一个表中的列,这样mysql才有可能使用索引来优化这个过程

    优化子查询

    • 子查询的优化最重要的是尽可能使用关联查询代替
    • 因为子查询结果会产生一个临时表

    优化group by 和 distinct

    • 关联查询做分组,按某个列进行分组,采用查找表标识列分组查找效率高
    select actor.first_name, actor.last_name,count(*) from film_actor inner join actor using(actor_id) group by actor.first_name, actor.last_name
    select actor.first_name, actor.last_name,count(*) from film_actor inner join actor using(actor_id) group by actor.actor_id;

    如果表标识列有重复字段上面这种写法会造成数据合并

    using与on的区别,参考文章:https://www.cnblogs.com/YC-L/p/14461585.html

    优化limit查询

    • 使用覆盖索引,而不是查询所有的列
    explain select film_id,description from film order by title limit 50,5
    explain select film.film_id,film.description from film inner join (select film_id from film order by title limit 50,5) as lim using(film_id);

    覆盖索引,参考文章:

    优化union查询

    • 如果没有规定过滤重复数据,就用union all
    • union会合并重复数据,本质上是mysql在查询过程中使用了distinct
    论读书
    睁开眼,书在面前
    闭上眼,书在心里
  • 相关阅读:
    POJ 2236 Wireless Network(并查集)
    POJ 2010 Moo University
    POJ 3614 Sunscreen(贪心,区间单点匹配)
    POJ 2184 Cow Exhibition(背包)
    POJ 1631 Bridging signals(LIS的等价表述)
    POJ 3181 Dollar Dayz(递推,两个long long)
    POJ 3046 Ant Counting(递推,和号优化)
    POJ 3280 Cheapest Palindrome(区间dp)
    POJ 3616 Milking Time(dp)
    POJ 2385 Apple Catching(01背包)
  • 原文地址:https://www.cnblogs.com/YC-L/p/14461586.html
Copyright © 2020-2023  润新知