索引原理

时间:2019-08-19
本文章向大家介绍索引原理,主要包括索引原理使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

一、初始索引

索引在MySQL中也叫是一种“键”,是存储引擎用于快速找到记录的一种数据结构。

索引是应用程序设计和开发的一个重要方面。若索引太多,应用程序的性能可能会受到影响。而索引太少,对查询性能又会产生影响,要找到一个平衡点,这对应用程序的性能至关重要。

二、索引的原理

通过不断地缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是说,有了这种索引机制,我们可以总是用同一种查找方式来锁定数据。

磁盘的I/O与预读:当一次IO时,不光把当前磁盘地址的数据,而是把相邻的数据也都读取到内存缓冲区内(一般为4K或8K)

索引的优缺点 读比写的多

  • 优点:查找速度快
  • 缺点:浪费空间;拖慢写的速度 (不要在程序中创建无用的索引)

三、索引的数据结构

1. 平衡树 b树

树状图是一种数据结构,它是由n(n>=1)个有限结点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。

特点:每个结点有零个或多个子结点;没有父结点的结点称为根结点;每一个非根结点有且只有一个父结点;除了根结点外,每个子结点可以分为多个不相交的子树

2. b+树

B+树是通过二叉查找树,再由平衡二叉树,B树演化而来

特性:

  1. 数据只存储在叶子节点
  2. 在叶子节点之间加入了双向地址连接,更方便的在子节点之间进行数据的读取
  3. 最左匹配特性
  4. 索引字段越小查询速度越快

四、聚集索引和辅助索引

1. 聚集索引

  1. 叶子结点存放的是一整行的信息
  2. 由于实际的数据也是聚集索引的一部分,并且数据只能按照一棵B+树进行排序,所以每张表只能有一个聚集索引就是主键,(1、如果未定义主键,MySQL取第一个唯一索引(unique)而且只含非空列(NOT NULL)作为主键,InnoDB使用它作为聚簇索引;2、如果没有这样的列,InnoDB就自己产生一个这样的ID值,它有六个字节,而且是隐藏的,使其作为聚簇索引)

聚集索引的优点:

  1. 它对主键的排序查找和范围查找速度非常快,叶子节点的数据就是用户所要查询的数据。如用户需要查找一张表,查询最后的10位用户信息,由于B+树索引是双向链表,所以用户可以快速找到最后一个数据页,并取出10条记录
  2. 范围查询(range query),即如果要查找主键某一范围内的数据,通过叶子节点的上层中间节点就可以得到页的范围,之后直接读取数据页即可

2. 辅助索引

  1. 叶子结点存放的是索引值和主键
  2. 回表: 只查询一个索引并不能解决查询中的问题,还需要到具体的表中去获取整行数据

3. 二者对比

聚集索引
1.纪录的索引顺序与无力顺序相同
   因此更适合between and和order by操作
2.叶子结点直接对应数据
 从中间级的索引页的索引行直接对应数据页
3.每张表只能创建一个聚集索引

非聚集索引
1.索引顺序和物理顺序无关
2.叶子结点不直接指向数据页
3.每张表可以有多个非聚集索引,需要更多磁盘和内容
   多个索引会影响insert和update的速度

五、MySQL索引管理

1. MySQL常用的索引

  1. mysql中的primary key是聚集索引
  2. unique,联合唯一是辅助索引
  3. 通过index创建的普通索引
  4. index(id,name)联合普通索引 index内有两个字段

2. 创建索引的方法

创建索引:create index ind_name on 表(name); 联合索引 create index ind_name on 表(id,name);

删除索引:drop index ind_name on 表;

六、正确的使用索引

1.所查询的列不是创建了索引的列

2.在条件中不能带运算或者函数,必须是"字段 = 值"

3.如果创建索引的列的内容重复率高也不能有效利用索引
重复率不超过10%的列比较适合做索引

4.数据对应的范围如果太大的话,也不能有效利用索引
between and > < >= <= != not in

5.like如果把%放在最前面也不能命中索引

6.多条件的情况

  1. and 只要有一个条件列是索引列就可以命中索引
  2. or 只有所有的条件列都是索引才能命中索引

7.联合索引

在多个条件相连的情况下,使用联合索引的效率要高于使用单字段的索引
where a=xx and b=xxx;
对a和b都创建索引 - 联合索引
create index ind_mix on s1(id,email)

  1. 创建索引的顺序id,email 条件中从哪一个字段开始出现了范围,索引就失效了
    select * from s1 where id=1000000 and email like 'eva10000%' 命中索引
    select count(*) from s1 where id > 2000000 and email = 'eva2000000' 不能命中索引
  2. 联合索引在使用的时候遵循最左前缀原则
    select count(*) from s1 where email = 'eva2000000@oldboy';
  3. 联合索引中只有使用and能生效,使用or失效

mysql 神器 explain

# 查看sql语句的执行计划
# explain select * from s1 where id < 1000000;
# 是否命中了索引,命中的索引的类型

开启慢日志

知道mysql可以开启慢日志
# 慢日志是通过配置文件开启
# 如果数据库在你手里 你自己开
# 如果不在你手里 你也可以要求DBA帮你开

两个名词

# 覆盖索引 using index
    # select count(id) from 表;
    # select id from 表 where id <20;
# 索引合并
    # 创建的时候是分开创建的
    # 用的时候临时和在一起了
    # using union 表示索引合并

7表联查速度慢怎么办?

# 1.表结构
    # 尽量用固定长度的数据类型代替可变长数据类型
    # 把固定长度的字段放在前面
# 2.数据的角度上来说
    # 如果表中的数据越多 查询效率越慢
        # 列多 : 垂直分表
        # 行多 : 水平分表
# 3.从sql的角度来说
    # 1.尽量把条件写的细致点儿 where条件就多做筛选
    # 2.多表尽量连表代替子查询
    # 3.创建有效的索引,而规避无效的索引
# 4.配置角度上来说
    # 开启慢日志查询 确认具体的有问题的sql
# 5.数据库
    # 读写分离
        # 解决数据库读的瓶颈

数据表\库的导入导出

# 备份表 :homwork库中的所有表和数据
    # mysqldump -uroot -p123 homework > D:\s23\day42\a.sql
    # 备份单表
    # mysqldump -uroot -p123 homework course > D:\s23\day42\a.sql
# 备份库 :
    # mysqldump -uroot -p123 --databases homework > D:\s23\day42\db.sql
# 恢复数据:
    # 进入mysql 切换到要恢复数据的库下
    # sourse D:\s23\day42\a.sql

开启事务,给数据加锁

# begin;#开始
# select id from t1 where name = 'alex' for update;
# update t1 set id = 2 where name = 'alex';
# commit;#结束

原文地址:https://www.cnblogs.com/saoqiang/p/11377541.html