Mysql 索引的基础(上)
要理解Mysql 中索引是如何工作的,最简单的方法是去看一看书的"索引部分":如果想在一本书中找到某个特定的主题,一般先看书的"索引",找到对应的页码。
在Mysql中,存储引擎用类似的方法使用索引,其先在索引中找到对应的值,然后根据匹配的索记录找到对应的数据行。加入要运行下面的查询:
select first_name FROM user where user_id = 5;
如果在user_id上建有索引,则mysql将使用该索引找到user_id=5的行,也就是说,mysql 先在索引上按值查找,然后返回所有包含该值的数据行。
索引可以包含一个或多个的值。如果索引包含多个列,那么列的顺序也十分重要,因为mysql 只能高效的使用索引的最左前缀列。创建一个包含两个列的索引,和创建两个只包含一个列的索引是大不相同的,下面将详细介绍。
索引的类型
索引有很多种类型,可以为不同的场景提供更好的性能.在Mysql中,索引是在存储引擎层实现的而不是服务器层实现的。所以没有同意的索引标准:不同的存储引擎的索引的工作方式不一样,也不是所有的存储引擎都支持所有类型的索引。即使多个存储引擎支持同一种类型的索引,其底层实现也可能不同。
下面我们来看看mysql支持的索引类型,以及他们的优缺点。
B-Tree 索引
当人们讨论索引的时候,如果没有特别指明类型,那么多半说的是B-Tree索引,它使用B-Tree数据结构来存储数据。大多数MySQL引擎都支持这种索引。
我们使用术语“B-Tree” ,因为MySQL 在create table 和其他语句中也使用该关键字。不过,底层的存储引擎也坑能使用不同的存储结构,例如,NDB集群存储引擎内部实际上使用了T-Tree 结构存储这种索引,即使其名字是Btree;innodb则使用的是B+Tree。
存储引擎以不同的方式使用了B-Tree索引,性能也各有不同,各有优势,例如,MyISAM 使用前缀压缩技术使得索引更小,蛋InnoDB 则按照原数据格式进行存储。在如MyIsam索引通过数据的物理位置引用被索引的行,而InnoDB索引则根据住建引用被索引的行。
B-Tree 通常意味着所有的值都是按照顺序存储的,而且每一个叶子页到根的距离相同。
B-Tree 索引能够加快访问数据的速度,因为存储引擎不在需要进行全表扫描来获取需要的数据,取而代之的是从索引的根节点开始进行搜索。根节点值中存放了指向叶子节点的指针,存储引擎根据这些指针向下层查找。通过比较节点页的值和要操作的值可以找到合适的指针进入下层子节点,这些指针实际上定义了子节点也中的值的上限和下限。最终存储引擎要么找到对应的值,要么该记录不存在。
叶子节点比较特别,他们的指针指向的是被索引的数据,而不是其他的叶节点页(不同引擎的指针类型不同)。根的深度和表的大小直接相关。
B-Tree 对索引列是顺序组织存储的,所以很适合查找范围数据。例如,在一个机遇文本域的索引树上,按字母书序传递连续的值进行查找是非常合适的,所以像“找出所有以I到K开头的名字”这样的查找效率会非常高。
请注意,索引对多个值进行排序的一句是CREATE TABLE 语句中定义的所以时的列的顺序。
可以使用B-Tree索引的查询类型。B-Tree 索引适用于全键值、键值范围或键前缀查找。其中键前缀查找只适用于根据最左前缀的查找。前面所述的索引对如下类型的查询有效:
全值匹配
全值匹配指的是和索引中所有的列进行匹配。
匹配最左前缀
前面提到的索引可以用于查找出所有姓为Allen的人,即只使用索引的第一列。
匹配列前缀
也可以值匹配莫一列的值开头部分。
匹配范围值
精确匹配某一列并范围匹配另一列
只访问索引的查询
因为索引树种的节点是有顺序的,所以除了按值查找之外,索引还可以用于查询中的ORDER BY操作。一般来说,如果B-Tree 可以按照某种方式查找到值,那么也可以按照这种方式用于排序,所以,如果ORDER BY 子句满足前面列出的集中查询类型,则这个索引也可以满足对应的排序需求。
下面是一些关于B-Tree索引的限制:
如果不是按照索引的最左列开始查找,则无法使用索引。例如,上面的列子中的索引无法用于超找名字为Bill的人,也无法查找某个特定生日的人,因为这两列都不是最左数据列。类似的,也无法超找姓氏以某个字母结尾的人。
不能跳过索引中的列。也就是说,前面所述的索引无法用于查找姓为Smith并且在特定日期出生的人。如果不指定名(first_name),则MySQL只能用于索引的第一列。
如果查询中有某个列的范围查询,则其右边的所有列都无法使用索引优化查找。例如查询WHERE last_name ='Smith' AND first_name LIKE "J%" AND dob = '1990-10-10',这个查询只能使用索引的前两列,因为这里LIKE是一个范围条件。如果范围查询列值的数量有限,那么可以通过使用多个等于条件来替代范围条件。
到这里读者应该可以明白,前面提到的索引列的顺序是多么重要:这些限制都和索引的顺序有关。在优化性能的时候,可能需要使用相同的列的顺序不同的索引来满足不同类型的查询需求。
也有些限制并不是B-Tree本身导致的,而是MySQL优化器和存储引擎使用索引的方式导致的,这部分限制在未来的版本中可能就不再限制了。
Mysql 索引的基础(上)的更多相关文章
- Dubbo入门到精通学习笔记(二十):MyCat在MySQL主从复制的基础上实现读写分离、MyCat 集群部署(HAProxy + MyCat)、MyCat 高可用负载均衡集群Keepalived
文章目录 MyCat在MySQL主从复制的基础上实现读写分离 一.环境 二.依赖课程 三.MyCat 介绍 ( MyCat 官网:http://mycat.org.cn/ ) 四.MyCat 的安装 ...
- mysql索引的使用[上]
数据库的explain关键字和联合索引优化: 本篇文章简单的说一下mysql查询的优化以及explain语句的使用.(新手向) 因为这篇文章是面向查询的,直观一点,首先我们创建一个表:student ...
- Mysql 索引的基础(下)
如果需要存储大量的URL并需要根据URL进行搜索查找.如果使用B-Tree 来存储URL,存储的内容就会很大,因为URL本身都很长.正常情况下会有如下查询: SELECT id FROM url WH ...
- 浅谈Mysql索引
文章原创于公众号:程序猿周先森.本平台不定时更新,喜欢我的文章,欢迎关注我的微信公众号. 我们都知道,数据库索引可以帮助我们更加快速的找出符合的数据,但是如果不使用索引,Mysql则会从第一条开始查询 ...
- Mysql系列(六)—— MySQL索引介绍
前言 索引种类 索引维护 如何使用索引 一.索引索引种类 MySQL中索引主要包含以下几种: 普通索引 唯一索引 主键索引 联合索引 全文索引 二.索引维护 在简述了索引的类型后,再来了解下如何维护索 ...
- 聊聊Mysql索引和redis跳表 ---redis的有序集合zset数据结构底层采用了跳表原理 时间复杂度O(logn)(阿里)
redis使用跳表不用B+数的原因是:redis是内存数据库,而B+树纯粹是为了mysql这种IO数据库准备的.B+树的每个节点的数量都是一个mysql分区页的大小(阿里面试) 还有个几个姊妹篇:介绍 ...
- MySQL 索引结构 hash 有序数组
MySQL 索引结构 hash 有序数组 除了最常见的树形索引结构,Hash索引也有它的独到之处. Hash算法 Hash本身是一种函数,又被称为散列函数. 它的思路很简单:将key放在数组里,用 ...
- Mysql索引总结(一)
数据库开发中索引的使用占了很重要的位置,好的索引会使数据库的读写效率加倍,烂的索引则会拖累整个系统甚至引发灾难. 索引分三类: index ----普通的索引,数据可以重复 unique ----唯一 ...
- Mysql索引基础
Mysql索引基础 基本概念: 索引是一种特殊的数据库结构,可以用来快速查询数据库表中的特定记录.索引是提高数据库性能的重要方式.索引创建在表上,是对数据库表中一列或多列的值进行排序的一种结构.可以提 ...
随机推荐
- Flask源码阅读笔记(一)
作者:acezio链接:https://zhuanlan.zhihu.com/p/21358368来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. flask的url r ...
- PreparedStatement可以有效地防止sql被注入
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import jav ...
- 生产环境搭建MySQL复制的教程(转)
[导读] 网络上有很多关于MySQL复制搭建的步骤和范例,以及手册上有一章完整的篇幅,讲述MySQL复制的原理.搭建步骤.优化等,但依然存在很多刚开始学习MySQL知识或者刚进入DBA行业的朋友咨询, ...
- MVC3.0,路由设置实现伪静态IIS中404错误
C# code? 1 2 3 4 5 routes.MapRoute("NewQueryTest.asp", "NewQueryTest ...
- Linux C 调用MYSQL API 函数mysql_escape_string()转义插入数据
Title:Linux C 调用MYSQL API 函数mysql_escape_string()转义插入数据 --2013-10-11 11:57 #include <stdio.h> ...
- ural 1640 Circle of Winter
这道题真的很无聊,就是找一个圆,至少有一个点在这个圆上,其他点不能在圆外,半径不定: #include <cstdio> #include <cstring> #include ...
- 欧拉计划之Largest palindrome product
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2 ...
- ISAP
跑的是比Dinic快辣. 更新:指针版.... #include<iostream> #include<cstdio> #include<cmath> #inclu ...
- DLL模块:C++在VS下创建、调用dll
1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等 ...
- python+mysql数据库的简单操作
最近接了一个任务,测试某项类似于收益情况报表的功能,因计算公式复杂,单纯手算过于复杂,所以想到写成脚本 根据python的分治原则,先整了几个函数用于实现计算逻辑,后发现数据输入过于繁琐,所以决定使用 ...