笔记记录自林晓斌(丁奇)老师的《MySQL实战45讲》

4) --深入浅出索引(上)

  一句话简单来说,索引的出现其实就是为了提高数据查询的效率,就像书的目录一样。

索引的常见模型

  哈希表:哈希表是一种以Key-Value存储数据的结构,只要输入key,就可以找到对应的value。哈希的思路很简单, 把值放在数组里,有一个哈希函数把key换算成一个确定的位置,然后把value放在数组的这个位置。不可避免地多个key值经过hash计算可能会出现同一个值,处理这种情况的一种方法是,拉出一个链表。查找时先通过key计算hash值找到这个链表,然后按顺序遍历链表。需要注意的是,hash存储的value并不是递增的,所以哈希索引做区间查询的速度很慢。所以,哈希表这种结构适用于只有等值查询的场景。比如Memcached及其他一些NoSQL引擎。

  有序数组:有序数组在等值查询和范围查询场景中的性能都很优秀。如果仅仅看查询效率,有序数组就是最好的数据结构了。但是,在需要更新数据时就很麻烦,在有序数组中间插入一个记录,就必须挪动后面所有的记录,成本太高。

  二叉搜索树:二叉搜索树的特点是:每个节点的左儿子小于父节点,父节点又小于右儿子。当然为了维持O(log(N))的查询复杂度,需要保证这棵树是平衡二叉树,为了保证是平衡二叉树所做的操作的时间复杂度也是O(log(N))。树可以有二叉,也可以有多叉。多叉树保证儿子从左到右递增。二叉树是搜索效率最高的,但是实际上大多数数据库存储并不使用二叉树。其原因是,索引不止存在于内存中,还要写到磁盘上。N叉树由于在读写性能上的优点,以及适配磁盘的访问模式,已经被广泛应用。以InnoDB为例,这个N的值差不多是1200.当树高是4时,已经可以存储17亿左右的数据了。

InnoDB索引模型:

  InnoDB使用了B+树的索引模型。索引类型可以分为主键索引和非主键索引。

  主键索引的叶子节点存储的是整行数据。在InnoDB中,主键索引也被称为聚簇索引(clustered index)

  非主键索引的叶子节点内容是主键的值,在InnoDB中,非主键索引也被称为二级索引(secondary index)

  因此,基于主键索引和普通索引的查询有很大的区别。如果使用主键索引ID来查询,只需要搜索ID对应的B+树。而如果使用非主键索引K来进行查询,需要先搜索K索引树,得到主键索引的值,再到主键索引树种进行搜索。这个过程称为回表

索引维护:

  B+树为了维护索引有序性,在插入新值的时候,需要做必要的维护。如果可以直接插入到末尾就会直接插入,否则则需要逻辑上挪动后面的数据,空出位置来。而如果要插入的位置的数据页已经满了,根据B+树的算法,需要申请一个新的数据页,然后挪动部分数据到新的页上,这个过程称为页分裂。整体空间利用率及性能都会受到相应影响。当然有分裂也有合并,暂且不谈了。基于以上索引维护内容,解释了为什么大多数建表语句都要求有自增主键。Not NULL PRIMARY KEY AUTO_INCREMENT。这样每次操作都会是追加操作,直接插入到末尾。另外,如果使用别的有业务逻辑的字段来做主键一是很难保证有序性。二来由于非主键索引储存的是主键的值,如果用较长的字段做主键,则普通索引叶子节点就会相应较大,普通索引所占用的空间也会变大。

  当然事无绝对,在特定场景下也可能使用业务字段做主键更合适。如:1.只有一个索引,2该索引是唯一索引。即典型的Key-Value场景。

上篇问题答案:

如果你是数据库负责人,你有什么方案来避免长事务呢?

  从应用端来说:1.确认是否使用了 set autocommit=0,你应该保证这个值为1。2.确认是否有不必要的只读事务。3业务连接数据库时,根据业务本身的预估,通过 SET MAX_EXECUTION_TIME命令控制每个语句的最长执行时间。

  从数据库端来说: 1.监控 information_schema.Innodb_trx表,设置长事务阈值,超过就报警或kill掉。2.Percona的pt-kill工具不错(这个笔者也不知道是什么东东,感兴趣可以搜一下)3.在业务功能的测试阶段要求输出所有general_log,分析日志。4.如果使用的是MySQL5.6或更新版本,将innodb_undo_tablespaces设置成2(或更大的值),这样即使真的回滚段过大,清理也更方便。(不明白)

问题:

  对于普通索引k,重建时可以这么写:

alter table T drop index k;
alter table T add Index(k);

  对于主键索引,可以这么写:

alter table T drop primary key;
alter table T add primary key(id);

  对于上面的重建索引的作法,说出你的理解。如果有不合时的,为什么?更好的作法是什么?

MySQL 笔记整理(4) --深入浅出索引(上)的更多相关文章

  1. 最全mysql笔记整理

    mysql笔记整理 作者:python技术人 博客:https://www.cnblogs.com/lpdeboke Windows服务 -- 启动MySQL net start mysql -- 创 ...

  2. MySQL 笔记整理(5) --深入浅出索引(下)

    笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> 5) --深入浅出索引(下) 这次的笔记从一个简单的查询开始: 建表语句是这样的 mysql> create table T ...

  3. MySQL 笔记整理(10) --MySQL为什么有时会选错索引?

    笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 10) --MySQL为什么有时会选错索引? MySQL中的一张表上可以 ...

  4. MySQL 笔记整理(16) --“order by”是怎么工作的?

    笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 16) --“order by”是怎么工作的? 在林老师的课程中,第15 ...

  5. MySQL 笔记整理(1) --基础架构,一条SQL查询语句如何执行

    最近在学习林晓斌(丁奇)老师的<MySQL实战45讲>,受益匪浅,做一些笔记整理一下,帮助学习.如果有小伙伴感兴趣的话推荐原版课程,很不错. 1) --基础架构,一条SQL查询语句如何执行 ...

  6. MySQL 笔记整理(20) --幻读是什么,幻读有什么问题?

    笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 20) --幻读是什么,幻读有什么问题? 我们先来看看表结构和初始化数据 ...

  7. [笔记整理]SQL Server 索引碎片 和 重建索引

    铺垫知识点: 数据库存储本身是无序的,建立了聚集索引,会按照聚集索引物理顺序存入硬盘.既键值的逻辑顺序决定了表中相应行的物理顺序 多数情况下,数据库读取频率远高于写入频率,索引的存在 为了读取速度牺牲 ...

  8. MySQL笔记(8)-- 索引类型

    一.背景 前面我们讲了SQL分析和索引优化都涉及到了索引,那么什么是索引,它的模型有什么,实现的机制是什么,今天我们来好好讨论下. 二.索引的介绍 索引就相当书的目录,比如一本500页的书,如果你想快 ...

  9. MySQL 笔记整理(11) --怎么给字符串字段加索引?

    笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 11) --怎么给字符串字段加索引? 日常工作中的登录系统,你很可能会使 ...

随机推荐

  1. Hive 本地调试方法

    关键词:hive, debug 本地调试(local debug) Hive 可分为 exec (hive-exec,主要对应源码里的ql目录) 和 metastore 两部分,其中exec对外有两种 ...

  2. dedecms自定义模型内容调用多个Ueditor

    关于dedecms后台如何整合百度编辑器(ueditor)网上有很多了,本站就不再赘述了,主要问题是,涉及到如果有内容模型的修改,则按照网络上介绍的方法会发现有BUG.当修改过默认的文章模型或者其他模 ...

  3. promise的理解

    为什么会有promise,他的作用是什么? promise主要是为了解决js中多个异步回调难以维护和控制的问题. 什么是promise? 从图中,我们可以看出,Promise是一个函数,这个函数上有在 ...

  4. 巧用PHP中__get()魔术方法

    PHP中的魔术方法有很多,这些魔术方法可以让PHP脚本在某些特定的情况下自动调用.比如 __construct() 每次实例化一个类都会先调用该方法进行初始化.这里我们讲一下__get() 魔术方法的 ...

  5. 怎么过滤 &nbsp;

    replace(str, " ", ""); 就是这么简单

  6. 推荐自学JAVA开发的三本书

    ---------------------------------------------------------------------------------------------------- ...

  7. JS基础整理面试题

    1.DOM和BOM的区别 DOM:document object model;文档对象模型,提供操作页面元素的方法和属性BOM:browser object model;浏览器对象模型,提供一些属性和 ...

  8. c# 钩子类

    using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using S ...

  9. Bugly 多渠道热更新解决方案

    作者:巫文杰 Gradle使用productFlavors打渠道包的痛 有很多同学可能会采用配置productFlavors来打渠道包,主要是它是原生支持,方便开发者输出不同定制版本的apk,举个例子 ...

  10. Apache Storm 核心概念

    前言: Storm读取实时数据流,并传递给处理单元,最终输出处理后的数据. 下图描述了storm的处理数据的主要结构. 元组(Tuple) :       元组是Storm提供的一个轻量级的数据格式, ...