看过一些人写的学习笔记,完全按书一字不漏照抄,内容很多,真不能叫笔记。遂自己整理了一份,取其精要。

更多笔记请访问@

目录
目录

索引概述

  • 索引即key

  • 在存储引擎层实现,不同引擎工作方式不同

  • 索引优化--最好的查询优化手段,可提效几个数量级

  • 两步查找数据:

磁盘查找索引节点(页),将其调入内存;

内存内业内查找数据

一. 索引类型

B-Tree

Hash

R-Tree空间数据索引

全文索引

1. B-tree索引

  • 支持引擎:InnoDB,MyISAM,Memory

  • 所有叶子值顺序存储,且到root高度一样
  • InnoDB,MyISAM B-tree工作方式异同:

InnoDB按原格式存储数据,MYISAM用前缀压缩技术

InnoDB用主键key索引数据行,MyISAM用物理位置索引数据行

  • 加速:存储引擎从root节点扫描,代替全表扫描
  • 叶节点指针-->被索引数据(data record)

1)B-Tree适用场景

1 全值匹配查询

所有列都匹配

2 最左前缀匹配

组合索引第一列

3 列前缀匹配

某列值开头

4 范围值匹配
5 一列精确一列范围匹配
6 覆盖索引查询

只访问索引即可取data,无须访问数据行

7 Order by排序

2) B-Tree不适用场景

  • 非最左列
  • 跳列

A C

  • 某列进行范围查询,其右边所有列无法再用索引

2. Hash索引

  • 访问哈希索引的数据很快

f(key)=slot

1) 支持引擎

Memory,NDB集群

2) 适用场景

索引全列匹配

3) 不适用场景

  • 不能从索引直接取data

哈希索引=哈希值+行指针,不存储字段值

  • 不能用于排序

哈希值有序,但索引数据无序

  • 不支持部分索引列匹配
  • 不支持范围查询

仅支持等值匹配 =,<=>,IN()

<=> NULL安全等于----操作数可为NULL

4) InnoDB自适应Hash索引

某些索引值被引用很频繁,InnoDB自动在内存B-Tree索引上创建一个Hash索引

用户无法控制和配置,但可关闭

5) 自定义hash索引

存储引擎不支持时,模拟创建hash

如何创建?

B-tree上创建伪hash索引

  • 仍在Btree上查找,但用hash索引值代替原Key(伪hash)
  • 须在where指定hash函数,不要用MD5(),SHA1()
select id from url
where url="www.mysql.com"
and
url_crc=CRC32("www.mysql.com")

其中urc_crc列为索引列

6) 处理Hash冲突

使用hash索引查询时,须在where指定常量

select id from url
where
url_crc=CRC32("www.mysql.com")
and
url="www.mysql.com"
select word,crc from words
where
crc=CRC32("gnu")
and
word="gnu"
@birthday problem

In probability theory, the birthday problem or birthday paradox concerns the

probability that,

in a set of {\displaystyle n} n randomly chosen people, some pair of them will have the same birthday.

By the pigeonhole principle, the probability reaches 100% when the number of people reaches 367 (since there are only 366 possible birthdays, including February 29). However, 99.9% probability is reached with just 70 people, and 50% probability with 23 people.

3. 空间数据索引 R-Tree

支持引擎:MyISAM

用作地理数据存储,如美团,滴滴定位服务

任意维度组合查询

须使用GIS函数维护数据,MySQL做的不好

4. 全文索引

  • 查找文本关键字,非比较索引键值
  • 类似搜索引擎
  • 相同列创建全文索引和B-Tree索引,不冲突

5. 其他索引

第三方引擎TokuDB

二. 索引好处

1. 好处

1) 减少扫描数据量

2) 避免排序和临时表

3) 随机IO转为顺序IO

2. 索引三星评价

评价索引是否适合某查询

第一星

索引将相关data行放到一起

第二星

索引的data行按查询所需顺序排序

第三星

索引含 查询全部列

三 .高性能索引策略

1. 独立的列

独立

索引列非表达式子式,或函数参数

两个错误:

1)索引列为表达式
select id from actor
where id + 1 = 5
2)
select ...
where
TO_DAYS(Current_DATE) - TO_DAYS(date_col) <= 10;

2. 前缀索引和索引选择性

1) 前缀索引

很长字符串,可索引开始的部分字符串

适用场景

BLOB,TEXT,很长的VARCHAR列

2) 优缺点

优点

节约索引空间

缺点

无法使用之做order by,Group by

无法使用做覆盖索引

3) 索引选择性

=不重复索引值/数据表记录总数
  • 不重复索引值<-->基数<-->cardinality
  • 记录总数<-->#T
  • 取值范围 [1/#T ,1]
  • 越高越好

选择性越高,过滤掉的行越多

4) 如何找到 前缀索引长度

思想

足够长(接近完整列),又不能太长(节约空间)

方法1 试验法

先算完整列频次,然后一个一个前缀试验

计算完整列频次

试验前3前缀

方法2 计算完整列选择性

使前缀选择性接近完整列选择性



5) 如何创建前缀索引

ALTER TABLE sakila
ADD KEY(city(7));

KEY(city(7))

3. 多列索引

1) 常见错误

每个列都创建单独索引,导致索引合并

create table t(
c1 int,
c2 int,
KEY(c1),
KEY(c2)
);

2) 索引合并表示索引建的不好,待优化

  • 多个索引相交(AND)不如组合索引好
  • 多个索引联合(OR)耗费CPU和内存资源
  • 优化器不计算(耗费CPU和内存资源)到查询成本中

4. 选择合适的索引列顺序

仅适用于BTree索引(按顺序存储数据)

Btree索引按从左到右顺序,依次扫描

索引可按升、降序扫描,满足Order by,Group by,Distinct

如何选择合适的索引列顺序

经验法则

无order by和Group by时,选择性最高的列放在前面

select * from payment
where staff_id=2 and customer_id=584;

key(staff_id,customer_id)还是key(customer_id,staff_id)?

5. 聚簇索引(clustered index)

InnoDB支持,MyISAM为非聚簇

聚簇

数据行,键值存储在一起

一个表只能有一个聚簇索引

聚簇特点

  • InnoDB通过主键聚集数据

主键未定义,用唯一非空索引聚集

无唯一非空索引,则隐式定义主键

  • 只聚集同一页面记录

聚簇优点

  • 相关数据保存在一起,如电子邮件(用户ID和全部邮件)
  • 数据访问更快(索引和数据都在BTree中)
  • 覆盖索引查询直接取页节点键值

聚簇缺点

数据全放内存时无优势(访问顺序不再重要)

插入速度依赖于插入顺序

InnoDB按主键顺序插入最快(否则插入后用optimize table优化表)

更新聚簇索引列代价很高

强制将每个更新行移动到新位置

页分裂问题

插入新行或,主键更新导致需移动行时

全表扫描慢

二级索引需两次索引查找

二级索引(secondary index,辅助索引)

叶节点保存行主键值,非指向data行的物理记录的指针

二级索引查找行步骤
  1. 叶子节点找到主键值
  2. 在聚簇索引找数据行

1 . InnoDB和MyISAM数据分布对比

InnoDB数据分布



InnoDB就是表,不用再像Myisam用单独列存储

聚簇索引叶子节点包含:

主键值

事物ID

回滚指针(用于事物和MVCC)

其他剩余列

聚簇和非聚簇表对比

2. InnoDB表按主键顺序插入行

无数据聚集,使用AUTO INCREMENT作为主键--保证按顺序写入

避免使用UUID(universal unique identifier)聚簇索引--导致插入变得随机

6. 覆盖索引

索引直接包含所需查询数据行,不需要回记录表(数据表)

只能用BTree做覆盖索引

支持InnoDB,myisam

Explain显示 Extra:Using index

覆盖索引优点

  • 索引条目小于数据行,减少了数据访问量
  • 范围查询IO少(索引列值顺序存储)
  • 对InnoDB表(聚簇索引)特别有用

二级主键能覆盖查询可避免对主键索引的二次查询

MyISAM覆盖索引可能会导致系统问题

MyISAM引擎内存只缓存索引,数据由OS缓存

ICP索引条件推送(index condition pushdown)

MySQL5.6开始支持

条件过滤推到存储引擎层完成,减少IO访问

7. 用索引扫描做排序

MySQL生成有序结果的两种方式

  • 排序
  • 按顺序扫描索引

Exlain Type:Using index

为何索引扫描比全表扫描慢?

如果索引不能覆盖查询全部列,则每扫一条索引记录必须回表(随机IO)

同一索引,既满足排序,又满足查找是最好的

何时能用索引进行排序?

  • 索引列序和order by顺序一致时
  • 且所有列排序方向一样

不能使用索引进行排序的场景

  • order by出现不同排序方向
  • order by引用非索引列
  • where和order by中的列无法组合为最左前缀
  • where第一列是范围条件
  • where出现IN(多个相等条件视为范围)

8. 压缩(前缀压缩)索引

MyISAM使用

减少索引大小(1/10磁盘空间)让更多索引进入内存

默认只压缩字符串,也可设置整数

只能从头开始扫描,无法二分

随机扫描导致适用于IO密集型(OLTP),不适用CPU密集型(OLAP)?

index1:perform

index2:performance-->7,ance

9. 冗余和重复索引

应删除重复索引

1) 重复索引

相同列创建多个索引



三个重复索引--unique,primary限制均通过索引实现

2) 冗余索引

应该删除冗余索引

两种冗余

已有key(A,B),再建key(A)

ID为主键,扩展索引为(A,ID)

建议

尽量扩展现有索引,而不是创建新索引,那样会导致冗余索引

10.删除未使用的索引

percona Toolkit--

pt-index-usage工具

11. 索引和锁

InnoDB存储引擎层完成条件过滤时(ICP--MySQL 5.6及以后),索引可减少访问行数,从而减少加锁数量

否则全表扫描并锁住所有行

覆盖索引失效:

  • InnoDB二级索引上用共享(读)锁,访问主键索引需要排他(写)锁
  • select for update比lock in share mode或非锁定查询慢

四. 索引和表维护

维护表三目的

找到并修复损坏的表

维护准确的索引统计信息

减少碎片

1. 找到并修复表

1) MyISAM表

check table--检查表

repair table--修复损坏的表

2) InnoDB表使用no-op ALTER

Alter TABLE innodb_tb ENGINE=INNODB;

2. 维护索引统计信息

优化器有时用索引统计信息估算扫描行数

ANALYZE TABLE更新统计信息避免错误

memory引擎不存储统计信息

MyISAM引擎存储统计信息在磁盘

Show Index from table查看索引基数(cardinality,索引列不同取值个数)

触发索引统计信息更新的三种情形

SHOW TABLE STATUS

SHOW INDEX

打开某些INFORMATION_SCHEMA表

3.减少索引和数据碎片

1)BTree索引会碎片化,降低查询效率

BTree随机访问是必须的,因为从root节点随机磁盘访问才能定位到叶子节点

2)三种数据碎片

行碎片

数据行存储在多个地方多个碎片中

行间碎片

逻辑上顺序的页或行,在磁盘上非顺序存储

剩余空间碎片

数据页中有大量不用的空余空间

MyISAM三种碎片都有,InnoDB无小碎片

3)如何消除碎片?

  • OPTIMIZE TABLE
  • ALTER TABLE tb ENGINE=;
  • 删除所有索引-->重建表 -->重建索引

五. 总结

索引三原则

1.单行访问很慢

最好一个数据块读取多行

2. 按顺序访问范围行很快

  • 顺序IO无需多次磁盘寻道,比随机IO快很多
  • 服务器按顺序读取数据,则不需要额外排序

3. 索引覆盖查询很快

避免了大量单行访问

高性能MySQL--索引学习笔记(原创)的更多相关文章

  1. 《高性能MySQL》学习笔记

    第1章 MySQL架构与历史 1.2 并发控制 MySQL在两个层面实现并发控制:服务器层与存储引擎层. 读锁和写锁: 在处理并发读或写时,可以通过实现一个由两种锁组成的系统来解决问题. 这两种锁通常 ...

  2. Mysql索引学习笔记

    1.btree索引与hash索引 下列范围查询适用于 btree索引和hash索引: SELECT * FROM t1 WHERE key_col = 1 OR key_col IN (15,18,2 ...

  3. Mysql数据库学习笔记之数据库索引(index)

    什么是索引: SQL索引有两种,聚集索引和非聚集索引,索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间. 聚集索引:该索引中键值的逻辑顺序决定了表中相应行的物 ...

  4. 《高性能MySQL》读书笔记--锁、事务、隔离级别 转

    1.锁 为什么需要锁?因为数据库要解决并发控制问题.在同一时刻,可能会有多个客户端对表中同一行记录进行操作,比如有的在读取该行数据,其他的尝试去删除它.为了保证数据的一致性,数据库就要对这种并发操作进 ...

  5. MySQL数据库学习笔记(九)----JDBC的ResultSet接口(查询操作)、PreparedStatement接口重构增删改查(含SQL注入的解释)

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  6. 基于【 MySql 】二 || mysql详细学习笔记

    mysql重点学习笔记 /* Windows服务 */ -- 启动MySQL net start mysql -- 创建Windows服务 sc create mysql binPath= mysql ...

  7. Mysql事务学习笔记

    Mysql事务学习笔记 1.事务概述 事务是数据库的执行单元,它包含了一条或多条sql语句,进行的操作是要么全部执行,要么全部都不执行. 2.事务执行命令 语法格式: start transactio ...

  8. MySQL数据库学习笔记(十二)----开源工具DbUtils的使用(数据库的增删改查)

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  9. MySQL数据库学习笔记(十)----JDBC事务处理、封装JDBC工具类

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  10. MYSQL数据库学习笔记1

      MYSQL数据库学习笔记1 数据库概念 关系数据库 常见数据库软件 SQL SQL的概念 SQL语言分类 数据库操作 创建数据库 查看数据库的定义 删除数据库 修改数据库 创建表 数据类型 约束 ...

随机推荐

  1. 每天一个Linux命令(16)--which命令

    把昨天的,留给昨天:今日,你将重新开始. 好的,在第一个阶段我们学习了  文件目录的操作命令: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ls cd pwd mkdir ...

  2. gulp快速入门&初体验

    前言 一句话先 gulp 是一个可以简单和自动化"管理"前端文件的构建工具 先说我以前的主要工作,我主要是做游戏服务端的,用c++/python,所以我对东西的概念理解难免要套到自 ...

  3. dll

    dll可以有一个入口点函数,系统会在不同的时候调用这个入口函数.这个调用是通知性质的,通常被dll用来执行一些与进程或线程有关的初始化和清理工作如果将dll的入口点函数命名为DllMain之外的其他名 ...

  4. AndroidStudio运行项目出现Unsupported method: AndroidProject.getPluginGeneration()错误解决办法

    一.错误描述 今天在使用AndroidStudio运行项目时出现了一个Unsupported method: AndroidProject.getPluginGeneration()错误,如下图所示: ...

  5. lab1-Junit&Eclemma

    Software Testing, Lab 1 March 10. 2016, by 赵国佺(3014218108) 一.     environment setup Firstly, I downl ...

  6. wemall app商城源码中基于JAVA通过Http请求获取json字符串的代码

    wemall-mobile是基于WeMall的Android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.分享其中关于通过Http请求获取json字符串的代码供 ...

  7. 1578: [Usaco2009 Feb]Stock Market 股票市场

    1578: [Usaco2009 Feb]Stock Market 股票市场 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 414  Solved: 1 ...

  8. 1620: [Usaco2008 Nov]Time Management 时间管理

    1620: [Usaco2008 Nov]Time Management 时间管理 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 506  Solved: ...

  9. 关于vue-clidown到本地后,拷贝文件库到另外一台电脑上npm run dev编译报错的处理

    这些天自己在用vue-cli项目,在家里的电脑下下来后写了一些demo,拿到公司继续开发的时候发现删除node_modules文件,运行npm install和npm run 百度,搜狗了好久都没有找 ...

  10. Android Weekly Notes Issue #248

    Android Weekly Issue #248 March 5th, 2017 Android Weekly Issue #248. 本期内容包括: 为什么有时候应该让你的应用崩溃(而不是一味保护 ...