1. 普通青年的索引使用方式

假设我们有一个用户表 tb_user,内容如下:

name age sex
jack 22
rose 21
tom 20
... ... ...

执行SQL语句:

SELECT name FROM tb_user WHERE age = 20;

默认情况下,MySQL需要遍历整张表,才能找到符合条件的记录。如果在age字段上建立索引,那么MySQL可以很快找到所有符合条件的记录(索引本身通过B+树实现,查起来很快。简单起见,想象一下二分查找和遍历查找的区别。)

2. 文艺青年的玩法

2.1 用冗余的联合索引加速查询

接着上面的例子,我们假设,tb_user表有一百万行,通常情况下,"WHERE age = 20"这样的语句,会返回几万行数据,实际测试下发现,速度不够快。

原因是,MySQL根据索引查询到符合条件的记录后,还需要到表空间里一一查找这些记录(实际上,索引里同时记录了age字段和关联记录的物理行号),这意味着,MySQL必须读取表空间多达几万次,才能返回最终结果。

聪明的你可能已经想到了,如果age字段的索引上有name字段的值话,MySQL就不用再费事地去访问表空间了。

最终解决方案:建立联合索引,让MySQL直接从索引中取出name字段的值

KEY `age_with_name` (`age`,`name`)

注意这里的顺序,必须是先age后name,反之不行(除非你是根据name查age)。

2.2 用冗余的联合索引加速排序

依然是之前的表,假设要做这样的查询:

SELECT * FROM tb_user ORDER BY age;

因为我们在age上有索引,所以排序是很快的(索引的本质就是将表记录的物理行号按照特定规则排序)

实际项目中,SQL可能比这个复杂些,比如:

SELECT * FROM tb_user WHERE sex='男' ORDER BY age;

这个时候,age字段上的索引就派不上用场了。因为,age索引是面向整个表的,筛选后的表和age索引是对不上的。

解决方案:依然是联合索引!

KEY `age_with_name` (`sex`,`age`)

这个联合索引,同时记录了sex和age,并且排序的规则是,先按sex排,sex相同时按age排。那么,通过"WHERE sex='男'",MySQL先对索引进行筛选,然后剩下的索引正好就是按照age排序的了。因此,整个SQL的排序速度依然很快。

最新文章

  1. checkbox做全选按钮
  2. Android学习杂记
  3. onclick传递参数
  4. 【VLC-Android】LibVLC API简介(相当于VLC的MediaPlayer)
  5. 链表操作,空间复杂度要求为O(1)
  6. gson使用详解
  7. [Angular + Webpack] ocLazyLoad compoment
  8. 3. SQL Server数据库状态监控 - 可用空间
  9. 【20171025晚】alert(1) to win 第五题 正则表达式过滤
  10. CentOS7部分调优命令
  11. mysql新增用户并开启远程连接
  12. OpenVDB for Mitsuba
  13. 图片的滑动缩放html、css、js代码
  14. java.lang.OutOfMemoryError及解决方案
  15. 【Python】【一些概念与对比】
  16. Orchard 前台权限与自定义权限
  17. jQuery源码分析-构造函数详解
  18. 基于Android应用《玩转英语》(总报告)
  19. 申请Let's Encrypt通配符HTTPS证书
  20. sqlserver年月日转汉字大写

热门文章

  1. springMVC_06数据的处理
  2. Java中net.sf.json包关于JSON与对象互转的坑
  3. C#设计模式之十一享元模式(Flyweight Pattern)【结构型】
  4. 在Java中进行序列化和反序列化
  5. Vue项目build打包部署到Tomcat后,刷新报404错误解决方案
  6. JavaScript是如何工作的:Web Workers的构建块 + 5个使用他们的场景
  7. crontab架构和格式
  8. 洛谷P4593 [TJOI2018]教科书般的亵渎(拉格朗日插值)
  9. 判断NaN的真假
  10. Android为TV端助力 事件分发机制