高性能索引设计

索引的优点

  • 减少了服务器需要扫描的数据量
  • 帮助服务器避免排序和临时表
  • 将随机I/O变成顺序I/O

索引的类型

B-Tree索引

  1. B-TREE通常就意味着里面存储的所有值都是有序的,并且查询的时候,不用全表扫描,而是按照索引结构查找,所以会更快
  2. INNODB使用的B+TREEB+TREEB-TREE的一个变种,区别是B+TREE为所有叶子结点增加了一个存储指向下个叶子结点的链指针和所有关键字都在叶子结点中出现.

适用的查询范围:

  • 全值匹配。和索引中的所有列进行匹配。
  • 匹配最左前缀。多列索引的最左前缀原则。例如一个多列索引为(A,B,C),当你的查询中包括AA,BA,B,C都可以用到索引,如果只有B,则无法用到该索引。
  • 匹配列前缀。like 'abc%'可以用到索引,而like '%abc%'就无法用到该类索引。
  • 匹配范围值其实就是范围查询,但当多列索引中有一列用到范围查询时,那么该列后面的索引都没法被用到。例如一个索引为(A,B,C),又一个查询为where A=1, B>1, C=1,那么这个查询只会用到(A,B,C)中的A,B列,C是不会被用到。
  • 只访问索引的查询。其实就是覆盖索引查询。

 hash索引

哈希索引是基于哈希表实现,在MySQL中,目前只有Memory引擎支持哈希索引。

 

适用场景

不支持场景

哈希索引

只支持等值比较查询

1、哈希索引的数据并不是按照索引值顺序存放的,因此无法用于排序查找和范围查找

2不支持部分索引列按匹配查找,使用索引列的全部内容来计算哈希值

高性能索引策略

1 独立的列

索引列不能是表达式的一部分,也不能是函数的参数

2 前缀索引和索引选择性

索引选择性:不重复的索引值和数据表记录总数(T)的比值,取值范围是从1/T ~1之间。索引的选择性越高,查询效率越高。唯一索引的选择性是1。

前缀索引:某个列太长,比如varchar类型很长的列,则必须使用前缀索引。关键在选择足够长的前缀保证较高的选择性,但又不能太长。方法:找到最常见的值列表,然后和最常见的前缀列表进行比对,然后逐渐增加前缀长度,直到前缀的选择性接近于完整列的选择性。

select count(distinct city) / count(*) from city_demo;

mysql> select count(distinct left(city,3))/count(*) as sel3,

    -> count(distinct left(city,4))/count(*) as sel4,

    -> count(distinct left(city,5))/count(*) as sel5,

    -> count(distinct left(city,6))/count(*) as sel6

    -> from city_demo;

+--------+--------+--------+--------+

| sel3   | sel4   | sel5   | sel6   |

+--------+--------+--------+--------+

| 0.3367 | 0.4075 | 0.4208 | 0.4267 |

+--------+--------+--------+--------+

1 row in set (0.01 sec)

mysql>

 

缺点:mysql无法使用其前缀索引做ORDER BY和GROUP BY,也无法使用前缀索引做覆盖扫描

3 多列索引

建立多列索引,那么选择合适的顺序相当重要。对于如何选择合适的索引顺序,有一个经验法则:将选择性最高的列放到索引最前列。

4 聚簇索引

聚簇索引把数据行存储在叶子页中,一个表中只能有一个聚簇索引。InnoDB存储引擎支持聚簇索引,在InnoDB中,聚簇索引其实就是主键索引。如果表中没有定义主键,InnoDB会选择一个唯一非空索引作为主键。如果没有这样的索引,InnoDB会隐式的定义一个主键来作为聚簇索引。聚簇索引的优点如下:

  • 可以把相关数据保存在一起。
  • 数据访问更快。
  • 使用覆盖索引扫描的查询可以直接使用页节点中的主键值。

如果表在设计和查询的时候能充分利用以上特点,将会极大提高性能。

当然,聚簇索引也有它的缺点:

  • 聚簇索引最大限度提高了I/O密集型应用的性能,但如果所有的数据都存放在内存中,聚簇索引就没有优势了。
  • 插入速度严重依赖插入顺序。这也是为什么InnoDB一般都会设置一个自增的int列作为主键。
  • 更新聚簇索引的代价很高,因为会强制InnoDB将每个被更新的行移到新的位置。
  • 如果不按顺序插入新数据时,可能会导致"页分裂"
  • 二级索引可能会比想象的更大。因为在二级索引的页子节点中包含了引用行的主键列。
  • 二级索引访问可能会需要进行回表查询。

5 覆盖索引

 如果一个索引包含或覆盖所有需要查询的字段值,我们就称之为覆盖索引 覆盖索引是一个非常有用的工具,可以极大的提升性能。所以可能一个索引对于某些查询是覆盖索引,而对于其他的查询则不是。覆盖索引其实是二级索引的特例,它满足了一个特定条件:

  • 索引行通常远小于数据行的大小,所以如果只需要索引,那么MySQL就会极大地减少数据访问量。
  • 因为索引是按照顺序存储的,所以对于I/O密集型的范围查询会比随机从磁盘读取每一行数据的I/O要少的多。
  • 由于InnoDB的聚簇索引,所以覆盖索引对InnoDB特别有用。

当发起一个覆盖查询的时候,在Explain中的Extra列中可以看到“Using index”的信息。对于select *,没有任何一个索引能够覆盖所有列。所以select * 可能会导致原本可以用到覆盖索引的查询而无法使用覆盖索引

6 索引条件下推(ICP)

ICP的目的是通过减少完整记录读取的数量来减少IO操作。在没有ICP的时候,WHERE条件中没有被索引用到的列的过滤是在MySQL服务层中,而有了ICP之后,这种过滤就直接在储存引擎层中完成了,而且是在二级索引回表查询前就完成了过滤,这就避免了大量数据传输,从而降低磁盘IO

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/419202.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

posix thread线程

1. pthread线程通过调用你提供的某些函数开始。这个“线程函数”应该只有一个void*型参数,并返回系统的类型。2. 通过向pthread_create函数传递线程函数的地址和线程函数调用的参数来参加线程。3. 线程可以通过pthread_self获取自己的ID。4. 除非线程的创建者或者线…

MySQL查询语句优化

慢查询原因 1 从数据库请求不需要的数据 例如业务只需要返回指定的列,sql查询全部列,或者多表关联返回全部列。某些相同数据被重查询多次,可以结合实际业务在初次查询后进行缓存,需要时候从缓存中取出 2 扫描额外的记录行 2 解…

python之装饰器详解

这几天翻看python语法,看到装饰器这里着实卡了一阵,最初认为也就是个函数指针的用法,但仔细研究后发现,不止这么简单。 首先很多资料将装饰器定义为AOP的范畴,也就是Aspect Oriented Programming面向切面编程的概念&am…

“睡服”面试官系列第十六篇之Symbol(建议收藏学习)

目录 1. 概述 2. 作为属性名的 Symbol 3. 实例:消除魔术字符串 4. 属性名的遍历 5. Symbol.for(),Symbol.keyFor() 6. 实例:模块的 Singleton 模式 7. 内置的 Symbol 值 7.1Symbol.hasInstance 7.2Symbol.isConcatSpreadable 7.3Sy…

POST请求传入中文参数,接收端乱码

问题描述&#xff1a;通过post请求调试短信接口发送出去后&#xff0c;客户端无法收到短信&#xff0c;中文内容乱码 追踪过程&#xff1a; 接口采用post请求进行&#xff0c;无法收取短信的接口代码如下&#xff1a; public static String sendPost(String url, Map<Stri…

LeetCode - Container With Most Water

题目&#xff1a; Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms…

TCP/IP协议模型

1. 数据链路层 作用(1) 实现网卡接口的网络驱动&#xff0c;以处理数据在以太网线等物理媒介上的传输   (2) 网络驱动程序隐藏了不同物理网络的不同电气特性&#xff0c;为上层协议提供一个统一的接口 应用ARP和RARP(Reverse Address Resolve Protocol)即逆地址解析协议&am…

【转】 Pro Android学习笔记(二九):用户界面和控制(17):include和merge

目录(?)[-] xml控件代码重用includexml控件代码重用merge横屏和竖屏landsacpe portraitxml控件代码重用&#xff1a;include 如果我们定义一个控件&#xff0c;需要在不同的layout中重复使用&#xff0c;或者在同一个layout中重复使用&#xff0c;可以采用include的方式。例如…

管理者一定会遇到的那些事

——极客时间——沈剑老师分享有感

Git使用攻略

Git使用攻略 merge&#xff0c;将develop合并到master# 切换到Master分支git checkout master# 将Develop分支合并到master git merge --no-ff develop 切换分支git checkout master 检出代码git checkout master 创建分支git branch newBranch查看本地分支git branch查看远程分…

Java停止线程的方式

1、使用中断标志位 public class StopThreadTest extends Thread {private boolean exit false;Overridepublic void run() {while (!exit) {try {System.out.println("i am running,please wait a moment");Thread.sleep(500);} catch (InterruptedException e) {…

Vim文本编辑器 指令簿(二)

常常处理文本以及常常须要写代码的人&#xff0c;都会有自己比較常常使用的编辑器&#xff0c;本人喜欢用Vim。理由就是Vim编辑器灵活&#xff0c;而且能够达到纯键盘操作&#xff0c;使用纯熟情况下&#xff0c;根本不须要鼠标操作。听起来是不是非常酷的&#xff1f;只是别高…

读《数学之美》

数学之美 数学的发展实际上是不断的抽象和概括的过程 目录 数学之美 第一章 第二章&#xff08;从规则到统计&#xff09; 第三章 统计语言模型 第四章 分词 第五章 隐马尔科夫模型 第六章 信息的度量和作用 第七章 贾里尼克和和现代语言处理 第八章 简单之美——布…

每天一个JavaScript实例-动态省份选择城市

<!DOCTYPE html> <html> <head> <meta http-equiv"Content-Type" content"text/html; charsetUTF-8" /> <title>每天一个JavaScript实例-动态省份选择城市</title> <script> var citystore new Array(); citys…