mysql 简单进阶 ———— 多列索引[一]
前文
整理一下mysql 的一些简单进阶技巧,来源于高性能mysql,但不是根据书的序列来的。
正文
库地址:
https://dev.mysql.com/doc/index-other.html
有一个问题,那就是我们为什么要创建多列索引呢?
这是要思考的一个问题。
为什么创建多列索引,而不是创建多个单列索引。需要弄明白这个问题,那么就需要知道索引是如何工作的。
为什么有索引这个东西呢?
就是因为我们摆放东西是要按照一定的规则去摆放的,为什么要按照规则摆放呢? 就是为了能够快速查找,这个是目的。
为什么建立多个索引,那么就是需要多种规则去摆放,以便于不同的查找方式。
那么多列索引和多个单个索引有什么区别呢? 多列索引是用多个列作为hash去进行排序的,而多个单列是建立多种规则去进行排序。
select film_id, actor_id
from sakila.film_actor
where actor_id = 1 or film_id =1;
举个例子,这个是建立多列索引号还是建立单个索引好?
不用猜想,做下实验。

那么现在建立了两个索引,那么看下运行是怎么样的。

这里可以看到,实际上是用到了两个索引,然后进行合并。
那么这里建立多个列索引有什么影响呢?

这里加了一个多列索引。

这里最后多列索引没有用,还是用的是两个单的索引。
原因是因为or,这个如果是两个列的hash作为结构的参考的话,那么实际上意义不大。

第一点现在已经理解了,那么第二点呢? 多个索引做联合操作时候,相当于做了两个查询,并且扫描了两次。
首先我们要知道这个扫描的29行是怎么来的。


是通过不同的索引扫描来的,10+19=29.
那么这里如果只创建一个索引怎么样?

看下分析结果:

几乎和前面没有变化。
原因为:

这张表有联合索引,查找actor_id 直接用了primary,也就是一个多列索引。
然后查找film_id 用了idx_fk_film_id 这个作为索引。
索引另外建立的索引都是多余的。
那么现在知道了一些多列索引和单列索引的区别了。
那么该如何选择多列索引呢?
在一个多列的b-tree 索引中,索引列的顺序意味着索引先按照最左进行排序,其次是第二列,这个可以看下我的c# linq系列。
索引可以按照升序或者降序进行扫描,以满足精确符合列顺序的order by,group by 和 distinct 等语句、
那么我们就会想到一个问题,那就是先把过滤多的放在第一列,这样使用where 的话,那么过滤的最多了。
但是依然需要考虑到group by 和 order by的情况。
先举个适用的例子:
select * from payment where staff_id = 2 and customer_id=584
如果这个语句很慢,那么我们考虑给他建立索引,那么哪个在前哪个在后呢?

显然我们应该选择customer_id,因为这个更少。
第一次过滤就可以过滤剩下30.

如果建立customer_id 索引,那么只需要过滤30里面的17即可。
但是上面有一个小小的问题,那就是我们指定了staff_id = 2 and customer_id=584 优化性能是最好的,但是会不会这个是特殊的。
那么就需要考虑整体性:

和前面的结果意义,customer_id 选择性高,因为 distinct 后的数量更多,也就基本意味着customer_id 筛选出来的条件更少。
所以你可以创建索引 alter table payment add key(customer_id,staff_id )
这里是个例子哈,也不是有and 就建立两个索引,这里customer_id 过滤出来的staff_id 都是30,其实建立customer_id索引就行。
那么还有一个问题,那就是是不是这个就通用了呢?
举一个反例:


结
下一节查询优化
mysql 简单进阶 ———— 多列索引[一]的更多相关文章
- MySQL Index--关联条件列索引缺失导致执行计划性能不佳
某系统反馈慢SQL影响生产,查看SLOW LOG发现下面慢SQL: SELECT COUNT(DISTINCT m.batch_no) FROM ob_relation r INNER JOIN ob ...
- mysql之多列索引
mysql的多列索引是经常会遇到的问题,怎样才能有效命中索引,是本文要探讨的重点. 多列索引使用的Btree,也就是平衡二叉树.简单来说就是排好序的快速索引方式.它的原则就是要遵循左前缀索引. 多个索 ...
- mysql索引之一:索引基础(B-Tree索引、哈希索引、聚簇索引、全文(Full-text)索引区别)(唯一索引、最左前缀索引、前缀索引、多列索引)
没有索引时mysql是如何查询到数据的 索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储10 ...
- Mysql的列索引和多列索引(联合索引)
转自:http://blog.chinaunix.net/uid-29305839-id-4257512.html 创建一个多列索引:CREATE TABLE test ( id ...
- 正确理解Mysql的列索引和多列索引
MySQL数据库提供两种类型的索引,如果没正确设置,索引的利用效率会大打折扣却完全不知问题出在这. CREATE TABLE test ( id INT NOT NULL, last_ ...
- mysql 多列索引的生效规则
mysql中 myisam,innodb默认使用的是 Btree索引,至于btree的数据结构是怎样的都不重要,只需要知道结果,既然是索引那这个数据结构最后是排好序:就像新华字典他的目录就是按照a,b ...
- mysql 开发进阶篇系列 3 SQL 优化(索引使用方法)
一. 本章介绍mysql中的索引的分类,存储,使用方法的介绍 1. 索引的存储分类 MyISAM存储引擎的表的数据和索引是自动分开存储的,各自是独立的一个文件, innodb 存储引擎的表的数据和索 ...
- MySQL InnoDB引擎B+树索引简单整理说明
本文出处:http://www.cnblogs.com/wy123/p/7211742.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...
- mysql多列索引和最左前缀
数据库的索引可以加快查询速度,原因是索引使用特定的数据结构(B-Tree)对特定的列额外组织存放,加快存储引擎(索引是存储引擎实现)查找记录的速度.索引优化是数据库优化的最重要手段. 如果查询语句使用 ...
- mysql多列索引优化
“把Where条件里面的列都建上索引”,这种说法其实是非常错误的! 这样一个查询,假设actor_id与film_id都单独建立索引 SELECT film_id , actor_id FROM sa ...
随机推荐
- Mysql常用存储引擎以及区别?
InnoDB:是Mysql的默认存储引擎,支持事务.外键.如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询之外,还包含很多的更新.删除操作,那么InnoDB存 ...
- CodeCraft-22 and Codeforces Round 795 (Div. 2)C. Sum of Substrings(分类讨论、贪心)
感觉分类讨论的能有点弱.遇到复杂一点的分类讨论的题目,代码就写的巨长. 首先观察到处在中间位置的1对答案的贡献是11,具体在中间哪个位置是没有关系的. 只有两端的两个位置是比较特殊的 \(1位置处的1 ...
- vscode中输入``自动将光标后面一个单词选中,左右加入<w>和</w>标签 - snippets 的命令调用
需求 vscode中输入``自动将光标后面一个单词选中,左右加入和标签 步骤0 准备需要安装插件 vim - 这里的点击两次按键激活的快捷键,这个插件可以设置 macros - 一次执行多个命令的插件 ...
- VS Code Snippet Generator 插件 生成 vscode代码片段
VS Code Snippet Generator 插件 生成 vscode代码片段
- ida使用入门指北
静态分析 快捷键 操作 作用 空格键 在反汇编窗口中,进行列表视图与图形视图之间的切换 TAB 在反汇编窗口中,进行汇编指令与伪代码之间的切换 Esc 和 Ctrl+Enter 翻页,返回前一页面 G ...
- Educational Codeforces Round 141:C. Yet Another Tournament
一.来源:Problem - C - Codeforces 二.题面 三.思路 读题: 其他人的胜场由位次决定,对于第i位,其胜场为i-1 人数为\(5·10^5\),不是5(看错了) 每个人和自己比 ...
- Java/Kotlin 密码复杂规则校验
原文地址: Java/Kotlin 密码复杂度校验 | Stars-One的杂货小窝 每次有那个密码复杂校验,不会写正则表达式,每次都去搜,但有时候校验的条件又是奇奇怪怪的,百度都搜不到 找到了个代码 ...
- mybatis之Mapped Statements collection does not contain value for...错误原因分析
错误原因有几种: 1.mapper.xml中没有加入namespace: 2.mapper.xml中的方法和接口mapper的方法不对应: 3.mapper.xml没有加入到mybatis-co ...
- Android Studio导入Android 4.2.2的WiFi-Display系统源码
Sink源码概述 Miracast Sink端源码最早出现在Android 4.2.2上,通过googlesource可以很方便的查看: https://android.googlesource.co ...
- Spring Boot学习日记8
学习了yaml文件的配置 <server> <port>8081<port> </server> # k-v键值对 name: xiaoqi #相当于n ...