MySQL 索引使用案例
索引使用案例
支持多种过滤条件
假设要设计一个在线约会网站,用户信息表有很多列,包括国家、地区、城市、性别、眼睛颜色,等等。网站必须支持上面这些特征的各种组合来搜索用户,还必须允许根据用户的最后在线时间、其他会员对用户的评分等对用户进行排序并对结果进行限制。如何设计索引满足上面的复杂需求呢?
现在需要看看哪些列选择性更高,哪些列在WHERE 子句中出现得最频繁。country、sex 列的选择性通常不高,但可能很多查询都会用到。所以考虑到使用的频率,建议在创建不同组合索引的时候将(sex,country )列作为前缀。但根据经验不是不应该在选择性低的列上创建索引的吗?这么做有两个理由:
- 第一点,如前所述几乎所有的查询都会用到sex 列。
- 更重要的一点是,索引中加上这一列也没有坏处,即使查询没有使用sex列也可以通过下面的“诀窍”绕过。这个“诀窍”就是:如果某个查询不限制性别,那么可以通过在查询条件中新增AND SEX IN('m','f') 来让MySQL选择该索引。
接下来,需要考虑其他常见WHERE 条件的组合,并需要了解哪些组合在没有合适索引的情况下会很慢。(sex,country,age )上的索引就是一个很明显的选择,另外很有可能还需要(sex,country,region,age )和(sex,country,region,city,age)这样的组合索引。
将aging放在索引的最后是因为age列多半是范围查询,而查询只能使用索引的最左前缀,直到遇到第一个范围条件列。前面的列在where子句中基本都是等于条件,故放置在age之前。
如何为一些生僻的搜索条件(比如has_pictures、eye_color、hair_color 和education)来设计索引呢?这些列的选择性高、使用也不频繁,可以选择忽略它们,让MySQL多扫描一些额外的行即可。
避免多个范围条件
从EXPLAIN 的输出很难区分MySQL是要查询范围值(>,<),还是查询列表值(in,not in)。EXPLAIN 使用同样的词“range”来描述这两种情况,但可以从值的范围和多个等于条件来得出不同。在我们看来,列表查询就是多个等值条件查询。这两种访问效率是不同的。对于范围条件查询,MySQL无法再使用范围列后面的其他索引列,但是对于“多个等值条件查询”则没有这个限制。
优化排序
使用文件排序对小数据集是很快的,但如果一个查询匹配的结果有上百万行的话会怎样?例如如果WHERE 子句只有sex 列,如何排序?可以增加一些特殊的索引来做排序,例如,可以创建(sex,rating )索引用于下面的查询:
mysql> SELECT<cols> FROM profiles WHERE sex='M' ORDER BY rating LIMIT 10;
而即使有索引,如果用户界面上需要翻页,并且翻页翻到比较靠后时查询也可能非常慢。下面这个查询就通过ORDER BY 和LIMIT 偏移量的组合翻页到很后面的时候:
mysql> SELECT<cols> FROM profiles WHERE sex='M' ORDER BY rating LIMIT 100000;
无论如何创建索引,这种查询都是个严重的问题。因为随着偏移量的增加,MySQL需要花费大量的时间来扫描需要丢弃的数据(需要将行数据加载出来?)。一个更好的办法是限制用户能够翻页的数量,实际上这对用户体验的影响不大,因为用户很少会真正在乎搜索结果的第10000页。
优化这类索引的另一个比较好的策略是使用延迟关联,通过使用覆盖索引查询返回需要的主键,再根据这些主键关联原表获得需要的行。这可以减少MySQL扫描那些需要丢弃的行数。下面这个查询显示了如何高效地使用(sex,rating )索引进行排序和分页:
mysql> SELECT <cols> FROM profiles INNER JOIN (
-> SELECT <primary key cols> FROM profiles
-> WHERE x.sex='M' ORDER BY rating LIMIT 100000, 10
-> ) AS x USING(<primary key cols>);
维护索引
减少索引和数据的碎片
B-Tree索引可能会碎片化,这会降低查询的效率。碎片化的索引可能会以很差或者无序的方式存储在磁盘上。
根据设计,B-Tree需要随机磁盘访问才能定位到叶子页,所以随机访问是不可避免的。然而,如果叶子页在物理分布上是顺序且紧密的,那么查询的性能就会更好。否则,对于范围查询、索引覆盖扫描等操作来说,速度可能会降低很多倍;对于索引覆盖扫描这一点更加明显。
行碎片(Row fragmentation),这种碎片指的是数据行被存储为多个地方的多个片段中。即使查询只从索引中访问一行记录,行碎片也会导致性能下降,InnoDB不存在这种碎片。
行间碎片(Intra-row fragmentation),行间碎片是指逻辑上顺序的页,或者行在磁盘上不是顺序存储的。行间碎片对诸如全表扫描和聚簇索引扫描之类的操作有很大的影响,因为这些操作原本能够从磁盘上顺序存储的数据中获益。
剩余空间碎片(Free space fragmentation),剩余空间碎片是指数据页中有大量的空余空。这会导致服务器读取大量不需要的数据,从而造成浪费。
对于MyISAM表,这三类碎片化都可能发生。但InnoDB不会出现短小的行碎片;InnoDB会移动短小的行并重写到一个片段中。可以通过执行OPTIMIZE TABLE 或者导出再导入的方式来重新整理数据,这对多数存储引擎都是有效的。
MySQL 索引使用案例的更多相关文章
- MySQL索引优化案例
这里我们分成三种情况进行分析,分别是单表,两表,三表 1.单表 CREATE TABLE IF NOT EXISTS `article`( `id` ) NOT NULL PRIMARY KEY AU ...
- MySQL索引优化案例浅析
MySQL是关系型数据库的一种,查询功能强,数据一致性高,数据安全性高,支持二级索引.但是性能比起非关系型数据库稍弱,特别是百万级以上的数据,很容易出现查询慢的现象.这时候要分析慢的原因,一般情况下是 ...
- Mysql 索引案例学习
理解索引最好的办法是结合示例,所以这里准备了一个索引的案例. 假设要设计一个在线约会网站,用户信息表有很多列,包裹国家,地区,城市,性别,眼睛颜色,等等.完整必须支持上面这些特征的各种组合来搜索用户, ...
- MySQL数据库索引类型、MySQL索引的优化及MySQL索引案例
关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车.对于没有索引的表,单表查询可能几十万数据就是瓶颈,而通常大型 ...
- MySQL全面瓦解25:构建高性能索引(案例分析篇)
回顾一下上面几篇索引相关的文章: MySQL全面瓦解22:索引的介绍和原理分析 MySQL全面瓦解23:MySQL索引实现和使用 MySQL全面瓦解24:构建高性能索引(策略篇) 索引的十大原则 1. ...
- MySQL索引原理及慢查询优化
原文:http://tech.meituan.com/mysql-index.html 一个慢查询引发的思考 select count(*) from task where status=2 and ...
- (转)MySQL索引原理及慢查询优化
转自美团技术博客,原文地址:http://tech.meituan.com/mysql-index.html 建索引的一些原则: 1.最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到 ...
- MySQL索引原理及慢查询优化 转载
原文地址: http://tech.meituan.com/mysql-index.html MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能 ...
- MySQL索引原理及慢查询优化(转)
add by zhj:这是美团点评技术团队的一篇文章,讲的挺不错的. 原文:http://tech.meituan.com/mysql-index.html MySQL凭借着出色的性能.低廉的成本.丰 ...
随机推荐
- Linux中系统时间同步ntpdate简介
Linux服务器运行久时,系统时间就会存在一定的误差,一般情况下可以使用date命令进行时间设置,但在做数据库集群分片等操作时对多台机器的时间差是有要求的,此时就需要使用ntpdate进行时间同步.所 ...
- 66.QT-线程并发、QTcpServer并发、QThreadPool线程池
1.线程并发一个程序内部能拥有多个线程并行执行.一个线程的执行可以被认为是一个CPU在执行该程序.当一个程序运行在多线程下,就好像有多个CPU在同时执行该程序.总之,多线程即可以这么理解:多线程是处理 ...
- 本地无法访问虚拟机的tomcat
查看 firewalld防火墙 是否开启 命令: firewall-cmd --state 如果是 running 关闭 firewalld防火墙命令: service firewalld stop ...
- ssh-正向与反向代理
常用参数 栗子 实战 常用参数 -N 告诉SSH客户端,这个连接不需要执行任何命令.仅仅做端口转发 -C 表示压缩数据传输 -f 告诉SSH客户端在后台运行 -q Quiet mode. 安静模式,忽 ...
- Python分析【公众号】历史评论,看看大家的留言情况!
大家好,我是辰哥~~~ 辰哥玩公众号有一段时间了,这期文章分析一波读者的留言情况,不仅可以对公众号的各位铁粉一目了然,还可以通过分析的结果对公众号的经营进行更好的规划.如读者留言的内容通常是内容是什么 ...
- SpringBoot:springBoot注解大全
springboot源码下载 https://github.com/spring-projects/spring-boot/releases 一.注解(annotations)列表 @SpringBo ...
- 部署JAX-WS Web服务作为战争中的Apache Tomcat(Deploying JAX-WS webservice as War in Apache Tomcat)
问 题 I have developed a webservice using JAXWS and able to run it from the eclipse on Tomcat 7 with ...
- Acunetix在SDLC中的安全性测试
DevOps只是害怕尝试新事物.它们用于Selenium测试,这些测试占用了管道并提供了难以解释的结果,但是与此同时,它们经常避开了DAST测试,这远没有那么麻烦. 由于他们的应用程序是完全用Java ...
- 63. Unique Paths II 动态规划
description: https://leetcode.com/problems/unique-paths/ 机器人从一堆方格的左上角走到右下角,只能往右或者往下走 ,问有几种走法,这个加了难度, ...
- WPF教程二:理解WPF的布局系统和常用的Panel布局
WPF的布局系统 了解元素的测量和排列方式是理解布局的第一步.在测量(measure)阶段容器遍历所有子元素,并询问子元素它们所期望的尺寸.在排列(arrange)阶段,容器在合适的位置放置子元素.理 ...