MySql教程

高并发,高性能,高可用MySQL 实战-怎么查询速度更快

本文主要是介绍高并发,高性能,高可用MySQL 实战-怎么查询速度更快,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

怎么查询速度更快

where查询太慢怎么办

  1. 覆盖索引
  • 覆盖索引指的是:查询语句从执行到返回结果均使用的是同一个索引
  • 覆盖索引可以有效减少回表
  • using index在查询计划里面就叫索引覆盖

是否会使用覆盖索引,看下面的例子: 第一个会使用,第二个不会使用
explain select inventory_id, store_id, film_id from inventory where store_id = 1;
explain select inventory_id, store_id, film_id, last_update from inventory where store_id = 1;

何时使用覆盖索引,当我们的一个表中经常要查询的数据就那么两个字段,如果我们给这两个字段建立联合索引,就可以避免二次回表,提升查询性能

总结,重点:

  • 覆盖索引(using index), 覆盖索引通过取消回表操作,提升查询效率(本质B+树的搜索从2次变为1次,提升查询效率)
  • 若数据的查询不只使用了一个索引,则不是索引覆盖
  • 可以通过优化sql语句或优化联合索引来使用索引覆盖

有更合适的索引不走,怎么办

  1. 如何确定用哪条索引
  • mysql在选取索引的时候,会参考索引的基数
  • 基数是mysql估算的,反应这个字段有多少种取值
  • 选取几个页算出取值的平均值,在乘以页数,即为基数

索引基数的应用
索引基数就是数据列所包含的不同值的数量

  1. 强制使用索引
    在sql语句后面加上 force index 强制使用索引

  2. 优化索引

  • analyze table 可以重新统计索引信息
  • 重新统计索引信息时,会重新计算索引的基数

总结,重点:

  • 根据索引的基数(cardinality),可以判断索引性能的好坏
  • 使用force index 强制使用索引
  • analyze table重新统计索引信息,修复基数信息
  • 索引基数越大,工作效率越好

count()这么慢怎么办

  1. count()函数用来统计计算结果集中不为null的个数
  • 首先存储引擎查询出结果集
  • server层逐个结果判断是否为null, 不为null则+1
  1. count(非索引字段)时,server层需要判断每个数据是否为null
  • 而且查询本身无法使用覆盖索引,理论上最慢
  1. count(索引字段)可以覆盖,依然需要每次判断字段是否为null
  • count(主键)同理,虽然主键默认非空,但是依然需要每次判断是否为null

count(索引字段)已经比count(非索引字段)效率要高了,因为不需要回表,但是还是需要每次判断字段是否为null

  1. count(1)只有扫描索引树,没有解析数据行的过程,理论更快
    但是server层依然需要判断1是否为null

  2. count(*) 一般用来返回数据表行数

  • MyISAM存储引擎中,count(*)直接返回数据库中记录的数据表行数
  • 由于InnoDB支持事务,所以数据库中不记录数据表的行数
  • mysql专门优化了count(*)函数,直接返回索引树中数据的个数

总结:

  • count(非索引字段),不会使用覆盖索引,最慢
  • count(索引字段), 会使用覆盖索引,但是会挨个判断索引字段的值是否为null, 不太快
  • count(1), 会挑一个索引字段,使用覆盖索引,但是还是会挨个判断1是否为null, 不太快
  • count(), mysql专门对count()做了优化,会挑一个索引字段,使用覆盖索引,并且直接返回索引中数据的个数,不会挨个判断是否为null, 最快

order by 这么慢,怎么办?

  1. mysql排序前会将查询的结果放到中间结果集
  2. 回表生成完整结果集
  3. 最高效,索引覆盖

    总结:
  4. mysql排序一般要需要生成中间结果集、排序、回表的过程
  5. 索引覆盖是最高效的需要处理排序的方式

随机选取这么慢怎么办

order by rand()原理

  1. 查询流程需要生成两个临时表
  2. 为什么会这么慢
  3. 解决方案-临时方法
select max(film_id), min(film_id) into @M,@N from film;
set @X = floor((@M-@N+1)*rand()+@N);
select title, description from film where film_id >= @X limit 1;
  1. 解决方案-业务方案
select film_id, title, description from film limit 1 offset 850;
-- 或,它们两个是等价的
select film_id, title, description from film limit 850, 1

总结:

3

这篇关于高并发,高性能,高可用MySQL 实战-怎么查询速度更快的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!