高性能mysql 第五章 索引部分总结
高性能索引
1。索引基础:索引的作用类似'目录'帮助Query来快速定位数据行。
1.1索引类型:
1.1.1
b-tree索引
b-tree(balance tree)索引:使用平衡树(非平衡二叉树)来保存索引值,叶子结点的到根节点的距离相差不超过1;对于不同的引擎,不同的索引类型叶子结点保存的值可以不同,同过索引找到数据行的方式也不同
可以使用b-tree索引的查询类型:1.全值索引;2.最左前缀;3.前缀索引;4.匹配范围;5.精准匹配某一列,范围匹配另一列(可以在看作最左前缀的扩大化)6.覆盖查询(只访问索引的查询)
局限:范围查询对复合索引的截断作用。
1.1.2
hash索引
hash索引:hash索引使用索引字段的hash值(散列值)作为索引寻址的标识,找到对应hash值时即可通过hash表对应的指针找到表数据。
散列值通过散列函数获得:书中对一般例子中使用的MD5()与sha1()两个散列函数的劣势做了分析(这两个函数本来是两种加密函数),两者得到的散列值长度过长,浪费空间;
hash冲突:使用一个hash函数传入两个不同的值可能产生一样的散列值,这就会导致hash冲突;解决办法一般为修改散列函数,与再散列;以及增加where条件人工消除hash冲突的影响三种。
文中提到:比较廉价的方式是截取md5()返回值的一部分作为散列值。
应该注意到:myisam,innodb引擎并不支持hash索引。但是innodb有一个特殊的功能“自适应hash索引”,使其给予b-tree索引建立一个hash索引,具有一定hash索引性质。
1.1.3空间数据索引(R-tree)
MYISAM支持R-tree,但是mysql数据库在空间索引方面是弱势的,pgsql的postGIS做的比较好。
1.1.4全文索引
全文索引与b-tree索引不冲突,适用于match,against操作。第七章会详细讨论
1.1.5其他索引
这里提到了tokudb引擎使用的分型树索引(fractal tree index);以及后面将要讲解的聚簇索引以及覆盖索引。
5.2
索引优点:
1.大大减少了服务器需要扫描的数据量;
2.帮助服务器避免了排序和临时表;
3.将随机io变为顺序io;
5.3高性能索引
5.3.1
左值才是索引列
索引不能使用表达式的一部分例:where a_id+1=2
5.3.2
前缀索引与索引的选择性
这一节详细讨论了前缀索引对于选择多常记录作为索引字段合适的问题:
提出了一个‘基数’的概念,即前缀对应唯一条目的数量与总数的笔直。前缀的基数应该接近完整列
例:count(distinct tt(city,3))/count(*)
这个值可以称为选择性
注:部分字段后缀索引有时候更加有效
5.3.3
索引合并
5.0以后会有一新增了索引合并这一优化策略:
问题: 对于一条sql中有多个单列索引可以用到,但是由于优化器对where子句的解析原因,只用到一个(一个索引即可过滤大量数据)或者干脆直接全表扫描(5.0以前优化器的缺陷)。
解决1:使用union all等保留字对数据进行sql进行拆分;
解决2:5.0mysql以上提供了一种索引合并策略,explain以后再会有类似extra:using union(primary,id_key)的提示项。
说明:索引合并大多数时候说明索引不太符合实际运用,需要优化更新索引。
5.3.4 合适顺序的索引
(1)索引项先后顺序对效率的影响
索引项先后顺序对效率的影响:多列索引中索引顺序的考量,1.可以由前缀索引的知识了解到,索引的顺序对索引的适用情景有较大的限制,这里讨论的是索引顺序对索引效率的影响,可以通过选择性计算的方式,将选择性高的数据放在前面(因为可以一次性过滤掉更多的数据)。 需要注意的是多列索引的索引项顺序是需要整体考量的,因为一条query的查询索引优化可能是另一条query的负优化。
(2)聚簇索引
(1)中讨论的索引项的顺序对索引的效率的影响。这里讨论索引中数据顺序对磁盘io的影响:
对于聚簇索引我们需要明白,它是innodb中的索引类型,在前面的章节我们了解innodb与myisam引擎索引结构的区别的时候说明了,两者对表数据的存放有一些区别,innodb不同于myisam将数据与索引分卡存放的方式,而是将数据行与索引存放在一起,存放了数据行的索引就是聚簇索引,数据行保存在顺序的索引叶子页中,这是io是顺序的,相比随即io能节省很多的io时间。 所以innodb表需要一个主键,没有显示定义的话,innodb也会隐式的定义一个主键索引顺序保存数据。
聚簇索引的缺点
聚簇索引要求索引与数据行一起顺序保存就使得非顺序插入,修改等需要需要操作原有数据的操作需要对数据的移位(这样才能保证数据的顺序性),非顺序数据插入后最好使用optimize table重新组织一下表。
数据加入的过程中往往可能需要对数据也进行也分裂与也合并,导致数据页中的数据并不是紧靠的,会占用跟多空间,微微的降低全表扫描的效率。、
二级索引(innodb中的非主键索引)除索引项以外需要保存主键值。
5.3.5innodb与myisam数据分布对比、
这里在上文聚簇索引中基本都有涉猎,就不再赘述了。
5.3.6覆盖索引
顾名思义覆盖索引就是索引中包含索引包含查询需要的数据,包括select子句,与where子句。
优点:
只需要访问索引,而不需要访问数据行就能获取需要的数据;
缺点:
使用条件很苛刻,需要索引使用包含足够多的索引项才能使得索引在query中能被用到。
说明:对于不能使用覆盖索引的数据,可以采用‘延迟关联’的方法来处理,即在子查询中使用覆盖索引,返回数据在进行外层查询。即覆盖查询获取普通查询的条件值。
5.3.7索引排序
索引排序可以在explain的 type列看到index,说明使用了索引扫描排序,如果该索引不是覆盖索引,那么要根据扫描到的索引项到磁盘去读取数据,产生了大量的随机io所以时间会比全表扫描更久。当然比文件排序还是要快不少。
索引排序在既有order by又有limit的语句中很有用!
5.3.8压缩索引
myisam对索引的一种优化方式;
对索引进行前缀压缩,即将索引中相同的部分用一个简单的标识符替换如perform与performance可以替换为7;ance。
由于索引值做了简化,索引中存在依赖关系,影响了索引的查找,是一种cpu换io的优化。
5.3.9冗余与重复索引
应该尽量拓展目前已有的索引,而不是去建立新索引,多列索引与单列索引就很容易产生重复。
可以节省空间,同时方便了io
5.3.10未使用索引
除了重复索引与冗余索引,未使用的索引也是应该被清除的对象。可以通过打开userstate服务器变量,让服务器运行一段时间,再查询对应的information_schema.index_statistics就能知道索引的使用情况。
5.3.11索引与锁
innodb的行锁是加在索引上的,依赖于索引的存在。其中还有一个细节是innodb在二级索引上使用共享锁,一级索引使用排它锁。
5.4索引使用案例
5.4.1支持多种过滤条件
最左前缀的推广
可以通过将多列索引的最左前缀值罗列出来,来使用多列索引中的后缀部分。
5.4.2避免多个范围条件
多等值条件与范围条件在explain中显示的type都是range,但是范围条件会导致多列索引的后续索引项无法使用索引,而多等值条件没有这样的限制。
如果mysql能实现松散索引扫描范围条件就能突破限制
5.4.3优化排序
针对group by与limit的优化:使用limit可能使返回数据大量的被抛弃。
解决1:通过反范式,预先计算,缓存来处理。(从数据源上精细化数据)
解决2:通过延迟关联,使用覆盖索引,以最小的代价来确定得数据行,在读取数据行的其他具体内容。
5.5索引的维护
5.5.1定位表损坏并修复
myisam的系统崩溃可能导致表损坏,使用check table来排查,通过repair或者一个不做任何有效操作的alter语句来修复表。
innodb的表不容易损坏(应该是数据索引的高度纠缠,可以以我修复),innodb需要进入强制恢复模式来恢复表
5.5.2更新索引统计信息
mysql提供两个api来查看索引值分布:
1.records_in_range(),传入边界值来获取其中的记录数。myisam返回准确值,innodb返回估计值。
2.info(),返回包括索引基数在内的各种数据。
可以通过analyze table来重新生成统计信息来处理优化错误的情况。myisam将索引统计信息保存在磁盘中,通过analyze table命令来维护,innodb不在磁盘中储存维护这些信息,而是通过随机索引访问来评估并将其储存在内存中。
show information_schema.statistics。
5.5.3mysql碎片整理
碎片类型:1行碎片,2行间碎片,3剩余空间碎片
myisam可能三种碎片都有,而innodb不会有行碎片,它会移动短小的行并重写到一个片段中。
清理用optimize table 或者使用 不做任何有效操作alter。
高性能mysql 第五章 索引部分总结的更多相关文章
- 高性能MySQL中的三星索引
高性能MySQL中的三星索引 我对此提出了深深的疑问: 一星:相关的记录指的是什么??(相关这个词很深奥,“相关部门”是什么部门) 二星:如果建立了B-Tree(B+Tree)索引,数据就有序了.三星 ...
- MySQL高级第二章——索引优化分析
一.SQL性能下降原因 1.等待时间长?执行时间长? 可能原因: 查询语句写的不行 索引失效(单值索引.复合索引) CREATE INDEX index_user_name ON user(name) ...
- 高性能mysql 第5章 创建高可用的索引
b-tree索引 一定程度上说,mysql只有b-tree索引.他没有bitmap索引.还有一个叫hash索引的,只在Memory存储引擎中才有. b-tree索引跟oracle中的大同小异. mys ...
- 高性能mysql 第6章 查询性能优化
查询缓存: 在解析一个sql之前,如果查询缓存是打开的,mysql会去检查这个查询(根据sql的hash作为key)是否存在缓存中,如果命中的话,那么这个sql将会在解析,生成执行计划之前返回结果. ...
- 高性能mysql 第六章查询性能优化 总结(上)查询的执行过程
6 查询性能优化 6.1为什么查询会变慢 这里说明了的查询执行周期,从客户端到服务器端,服务器端解析,优化器生成执行计划,执行(可以细分,大体过程可以通过show profile查看),从服务器端返 ...
- 高性能mysql第6章
第6章,优化配置 https://www.cnblogs.com/musings/p/5913157.html 1:服务器读取的配置文件,可以使用下面的命令查询 admin@iZwz92c0zpe8t ...
- 高性能MySQL第1章知识点梳理
1. MySQL的逻辑架构 最上面不是MySQL特有的,所有基于网络的C/S的网络应用程序都应该包括连接处理.认证.安全管理等. 中间层是MySQL的核心,包括查询解析.分析.优化和缓存等.同时它还提 ...
- 【MySQL高级特性】高性能MySQL第七章
2017-07-25 14:15:43 前言:MYSQL从5.0和5.1版本开始引入了很多高级特性,例如分区.触发器等,这对有其他关系型数据库使用 背景的用户来说可能并不陌生.这些新特性吸引了很多用户 ...
- 高性能mysql 第7章 mysql高级特性之分区表
分区表: 分区表是一个独立的逻辑表,底层通过多个物理表实现. mysql实现分区表的方式是对底层表的封装.这意味着没有全局索引,索引是建立在底层的每个表上的(跟ORACLE不一样). 用到分区表的几种 ...
随机推荐
- 一天一点Zynq(1)xilinx-arm-linux交叉编译链 安装总结以及资源更新
结束了对xilinx-arm-linux交叉编译链安装后,总结一下整个过程,方便后来的研究者们,少走点弯路. 关于xilinx-arm-linux交叉编译链的安装,网上一搜一大把,可是有的资料中的资源 ...
- CloudStack学习-1
环境准备 实验使用的虚拟机配置 Vmware Workstation 虚拟机系统2个 系统版本:centos6.6 x86_64 内存:4GB 网络:两台机器都是nat 磁盘:装完系统后额外添加个50 ...
- js实现下拉框模糊查询
keyup方法触发模糊查询 list : Array<any> //下拉列表所有内容 filtList:Array<any> //过滤后的内容 inputContent : s ...
- ﺑﯘﻟﺒﯘﻟﻼﺭ--思恋--IPA--维吾尔语
很美的维语歌曲, 迪里拜尔将之唱得十分动人心弦.
- 提供一个Java字符串转整型数组的方法
package edu.yuliang.Data_Structure_Basics; import java.util.Scanner; public class new_string { publi ...
- jQuery-1.样式篇---属性与样式
jQuery的属性与样式之.attr()与.removeAttr() 每个元素都有一个或者多个特性,这些特性的用途就是给出相应元素或者其内容的附加信息.如:在img元素中,src就是元素的特性,用来标 ...
- Oracle数据库死锁和MySQL死锁构造和比较
最近在复习数据库的事务隔离性,顺便构造了一下在Oracle上和MySQL上的死锁以比较异同. 在Oracle上面的实验 在Oracle中,因为是显式提交,所以默认可以认为在一个会话中若没有使用comm ...
- 链接属性external的使用
//demo1.c #include<stdio.h> ; //static int x = 10; void print(void) //static void print(void) ...
- Linux命令学习之路——内容剪切:cut
使用者:所有角色 用法:cut [ -bcdfn ] [ --complement ] filename 作用:截取文件中的部分字段用于展示或存储到新文件中 应用场景: 1.内容展示 : 截取一个或多 ...
- java.math.*;(一)
package com.test; /* Math类: java.lang.Math类中包含基本的数字操作,如指数.对数.平方根和三角函数. java.math是一个包,提供用于执行任意精度整数(Bi ...