美文网首页
SQL 索引

SQL 索引

作者: wpf_register | 来源:发表于2019-09-29 09:37 被阅读0次

原文链接1
原文链接2

什么是索引

索引的目的在于提高查询效率。

一 般的应用系统,读写比例在10:1 左右 ,而且插入操作的一般的更新操作很少出现性能问题,在生产环境中,我们遇到的更多的,也是最容易出问题的,还是一些复杂的查询操作。而查询中,索引则显示得特别重要。

索引在 MySQL 中也叫做“键”,是存储引擎用于快速找到记录的一种数据结构。索引对于良好的性能非常关键,尤其当表中的数据特别大时,索引以俞发重要。

磁盘 IO 与预读

磁盘 IO是非常高昂的操作,计算机操作系统做了一些优化,当一次 IO时,不光把当前磁盘地址的数据,而是把相邻的数据也都读取到内存缓冲区内。局部预读性原理告诉我们,当计算机访问一个地址的数据的时候,与其相邻的数据也会很快被访问到。

每一次IO读取的数据我们称之为一页(page)。具体一页有多大数据跟操作系统有关,一般为4k或8k,也就是我们读取一页内的数据时候,实际上才发生了一次IO,这个理论对于索引的数据结构设计非常有帮助。

索引的数据结构

数据结构要求,每次查找数据时把磁盘IO次数控制在一个很小的数量级,最好是常数数量级。 B+ 树应运而生。

示例如图
  1. 浅蓝色的块称之为一个磁盘块,每个磁盘块包含几个数据项(深蓝色所示)和指针(黄色所示)。
  2. 如磁盘块1包含数据项17和35,包含指针P1、P2、P3,P1表示小于17的磁盘块,P2表示在17和35之间的磁盘块,P3表示大于35的磁盘块。
  3. 真实的数据存在于叶子节点即3、5、9、10、13、15、28、29、36、60、75、79、90、99。非叶子节点只不存储真实的数据,只存储指引搜索方向的数据项,如17、35并不真实存在于数据表中。
B+树的查找过程

查找数据项29:
首先会把磁盘块1由磁盘加载到内存,此时发生一次IO,在内存中用二分查找确定29在17和35之间,锁定磁盘块1的P2指针,内存时间因为非常短(相比磁盘的IO)可以忽略不计,通过磁盘块1的P2指针的磁盘地址把磁盘块3由磁盘加载到内存,发生第二次IO,29在26和30之间,锁定磁盘块3的P2指针,通过指针加载磁盘块8到内存,发生第三次IO,同时内存中做二分查找找到29,结束查询,总计三次IO。

3层的b+树可以表示上百万的数据,如果上百万的数据查找只需要三次IO,性能提高将是巨大的,如果没有索引,每个数据项都要发生一次IO,那么总共需要百万次的IO,显然成本非常非常高。

B+ 树性质
  1. 索引字段要尽量的小
  2. 索引的最左匹配特性(即从左往右匹配)
MySQL 索引分类
  1. 普通索引 index: 加速查找
  2. 唯一索引
    主键索引:primary key :加速查找+约束(不为空且唯一)
    唯一索引:unique: 加速查找+约束 (唯一)
  3. 联合索引
    primary key(id,name):联合主键索引
    unique(id,name):联合唯一索引
    index(id,name):联合普通索引
  4. 全文索引fulltext : 用于搜索很长一篇文章的时候,效果最好。
  5. 空间索引spatial : 几乎不用
创建/删除索引

key 列
PRI 主键索引
MUL 辅助索引
UNI 唯一索引
在创建表时就创建(需要注意的几点)

    create table s1(
    id int ,  
    # 可以在这加primary key
    # id int index不可以这样加索引,因为index只是索引,没有约束一说,不能像主键,还有唯一约束一样,在定义字段的时候加索引
    name char(20),
    age int,
    email varchar(30)
    index(id) #可以这样加
    #primary key(id) #也可以在这加
    );

在创建表后在创建

    create index name on s1(name); #添加普通索引
    create unique age on s1(age);#添加唯一索引
    create index name on s1(id,name); #添加普通联合索引
    alter table s1 add primary key(id); #添加住建索引,也就是给id字段增加一个主键约束

    ALTER TABLE 表名 ADD INDEX idx_索引名(索引列); #建立指定列的单列索引
    ALTER TABLE 表名 ADD INDEX idx_索引名(索引列(n)); #建立指定列的前缀索引(n为前缀长度)
    ALTER TABLE 表名 ADD INDEX idx_索引名(索引列1,索引列2,...); #建立多列的联合索引

删除索引

    drop index id on s1;
    drop index name on s1; #删除普通索引
    drop index age on s1; #删除唯一索引,就和普通索引一样,不用在index前加unique来删,直接就可以删了
    alter table s1 drop primary key; #删除主键(因为它添加的时候是按照alter来增加的,那么我们也用alter来删)
索引使用
  1. 覆盖索引
select * from s1 where id=123; 

sql命中了索引,但未覆盖索引
利用id=123到索引的数据结构中定位到该id在硬盘中的位置,或者说再数据表中的位置。
但是我们select的字段为*,除了id以外还需要其他字段,这就意味着,我们通过索引结构取到id还不够,
还需要利用该id再去找到该id所在行的其他字段值.

相关文章

  • SQL Server数据库高级进阶之索引优化实战演练

    一、SQL Server索引优化本质 二、SQL Server索引存储机制 三、SQL Server索引类型分类 ...

  • MySQL正确使用索引

    需要解决的问题 知道sql为什么会走索引? 为什么有些sql不走索引? sql会走那些索引,为什么会这么走? In...

  • SQL语句的优化

    sql语句的优化:多使用共享语句 尽量使你的sql语句能够使用索引。怎样使sql语句能够使用到索引呢:当sql语句...

  • 索引设计指南

    Sql Server索引设计指南——脑图链接 参考资料:SQL Server 索引设计指南Clustered an...

  • MySQL 如何正确的使用索引

    学习索引,主要是写出更快的sql,当我们写sql的时候,需要明确的知道sql为什么会走索引?为什么有些sql不走索...

  • MySQl优化学习笔记(七)SQL优化简介

    一、SQL优化简介 1、我们平时说的SQL优化就是优化SQl语句和索引(通俗说就是使用什么样的SQL语句能够让索引...

  • mysql(普通索引-单列索引)

    普通索引命名规则 一般性索引用ind_开头,后面跟字段名 demo sql 创建表之前索引(对比demo sql)...

  • MySQL索引知多少

    mysql索引 总结关于mysql的索引,查询优化,SQL技巧等 1 索引类型 B-Tree索引 Hash索引 ...

  • 索引失效

    在编写sql语句时,一般都会用到索引来提升sql性能,但是有些sql语句使用索引是不生效的。 is null 和...

  • sql中强制使用索引

    在工作中遇到sql查询数据较慢时,用explain查看sql索引,发现添加的索引没有生效,那么可以使用强制索引 但...

网友评论

      本文标题:SQL 索引

      本文链接:https://www.haomeiwen.com/subject/bjyiuctx.html