原文:MySQL性能优化(三):索引

版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。

一 索引原理

如果一本新华字典假如没有目录,想要查找某个字,就不得不从第一页开始查找,一直找到最后一页(如果要找的字在最后一页),这个过程非常耗时,这种场景相当于数据库中的全表扫描的概念,也就是循环表中的每一条记录看看该记录是否满足条件,扫描次数为表的总记录数。

新华字典中都会有目录都有查找方法(比如按拼音查找、按部首查找),假如按拼音查找,我们根据拼音就能瞬速定位到要找的汉字,而这个汉字后面还有这个汉字对应的页数,我们直接翻到该页就能找到,整个查找过程非常快,用时非常短。这个原理就是数据库中索引的原理。这里的按拼音查找、按部首查找是两种不同的查找方式,通过每种方式都能快速找到,在数据库中也有很多查找方式,称之为索引方法,有BTREE、HASH两种方式

BTREE:一颗倒立的树,每个节点都有父节点,父节点下面的节点称之为子节点(叶子节点),比父节点值小的位于父节点下面的左方,比父节点值大的子节点放置在父节点下面的右下方。

记录索引列的值和对应的记录所在的磁盘位置,每次排除掉一半, 检索一次相当排除掉2的n次幂,使用二叉树排除30次相当于全表排除10亿次。比如查询id=11的值,首先和6比,比6大就排除掉左边的,继续和9比较,11比9大,又排除掉左边的一般,和11进行比较,相等就找到了结果。当数据量很大的时候,每次都排除掉一半,排除的数据量是非常惊人的。

Hash:Hash索引只能等值匹配,想范围查询,左前缀查询都不适用, 其余大部分场景

为什么要使用索引?

  • 索引大大减少了存储引擎需要扫描的数据量
  • 索引可以帮助我们进行排序以避免使用临时表
  • 索引可以把随机IO变为顺序IO

二 索引类型

  • 主键索引(primary key):添加了主键就有了主键索引,可以在创建表的时候指定主键,也可以在创建成功之后再增加
  • 唯一索引(unique):添加了唯一约束就有了唯一索引,唯一索引可以有多个null
  • 普通索引(normal):一般是先建表,后面再创建索引,普通索引使用的最多
  • 全文索引(fulltext):主要针对文本段落等,全文索引只能应用MyISAM引擎
  • 空间索引(spatial): 使用较少,并且mysql支持的还不好
关于唯一性有两种做法:
  • 通过程序来保证数据的唯一性
  • 业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引。 说明:不要以为唯一索引影响了 insert 速度,这个速度损耗可以忽略,但提高查找速度是明显的;另外即使在应用层做了非常完善的校验控制,只要没有唯一索引,根据墨菲定律,必然有脏数据产生。(来自阿里巴巴Java开发手册)
关于全文索引:

全文索引只能用于MyISAM引擎,通常如果用到全文索引一般通过Elasticsearch、Solr、Lucene等技术来实现。

三:索引语法

1. 创建索引

①:语法
-- 创建普通索引:
create index 索引名 on 表(列1【ASC|DESC】, 列2 ASC|DESC】) -- 创建唯一索引
create unique index on 表名(列名)
  • 1
  • 2
  • 3
  • 4
  • 5
②:索引命名规则
  • 主键索引名为 pk_字段名,pk即 primary key
  • 唯一索引名为 uk_字段名; uk即 unique key
  • 普通索引名则为 idx_字段名;idx即index的简称。
③:索引字段

一个索引可以针对一个字段进行创建,也可以指定多个字段创建复合索引。

④:在哪些列上适合添加索引
  1. 频繁作为查询条件的列或者连接条件的列适合创建索引,即Where中的列或者是连接子句指定的列
  2. 唯一性太差的字段不适合创建索引,如性别
  3. 更新非常频繁的字段不适合创建索引
  4. 不作为where条件的字段不要创建索引
  5. 选用NOT NULL的列
  6. 尽量使用字段长度小的列作为索引
  7. 使用数据类型简单的列(int 型,固定长度)
⑤:索引顺序

ASC | DESC 选项 除非显式指定降序 (DESC),否则列以升序 (ASC) 排序。不管索引是升序排列还是降序排列,在执行升序或降序 ORDER BY 操作时都会使用索引。但是如果通过混合的升序和降序属性来执行 ORDER BY,则仅当索引是用同样的升序和降序属性创建的时才使用索引。

-- 可以显式指定索引字段的顺序,默认为升续
CREATE INDEX idx_username ON tbl_user(username ASC); -- 对于较长的字符内容可以指定前N个字节创建索引,没必要为整个值都创建索引
CREATE INDEX idx_username ON tbl_user(contnet(20) ASC); -- 复合索引:基于多个字段共同创建索引(区分度最大的字段放在前面,经常会被使用到的列在前面)
CREATE INDEX idx_username_email ON tbl_user(username, email); -- 删除索引
DROP INDEX idx_username ON tbl_user; -- 查看某个表的索引,两种方式效果一样
SHOW INDEX FROM tbl_user;
SHOW KEYS FROM tbl_user;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
⑥:注意
  • 如果是先建表,表中有比较多的数据,此时再创建索引,创建完索引需要等一会,让索引在后台创建完再使用
  • 索引数量控制,单张表中索引数量不应超过5个,单个索引中的字段数不超过5个。
  • 索引存储的位置位于mysql安装的/xxx/data目录下, 索引能提高查询速度,但对update/delete/insert变慢,因为还要重新维护索引文件,一般情况下查询次数远大于增删改

2. 查询索引

show index from 表名;
show keys from 表名;
  • 1
  • 2

3. 修改索引

一般是先删除再创建

4. 删除索引

alter table xxx drop index 索引名;

alter table xxx drop primary key;
  • 1
  • 2
  • 3
- 删除重复和冗余的索引(第三方工具需要额外安装)
pt-duplicate-key-checker h=127.0.0.1 -- 更新索引统计信息及减少索引碎片
ANALYZE TABLE <table_name> -- 清理碎片(注意会锁表)
OPTIMIZE table <table_name>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

查询没有使用到的索引

SELECT
object_schema,
object_name,
index_name,
b.table_rows
FROM performance_schema.table_io_waits_summary_by_index_usage a
JOIN information_schema.tables b ON a.object_schema = b.table_schema AND a.object_name = b.table_name
WHERE index_name IS NOT NULL
AND count_star = 0
ORDER BY object_schema, object_name;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

MySQL性能优化(三):索引的更多相关文章

  1. MySQL性能优化:索引

    MySQL性能优化:索引 索引提供指向存储在表的指定列中的数据值的指针,然后根据您指定的排序顺序对这些指针排序.数据库使用索引以找到特定值,然后顺指针找到包含该值的行.这样可以使对应于表的SQL语句执 ...

  2. Mysql性能优化三(分表、增量备份、还原)

    接上篇Mysql性能优化二 对表进行水平划分 如果一个表的记录数太多了,比如上千万条,而且需要经常检索,那么我们就有必要化整为零了.如果我拆成100个表,那么每个表只有10万条记录.当然这需要数据在逻 ...

  3. mysql性能优化之索引优化

    作为免费又高效的数据库,mysql基本是首选.良好的安全连接,自带查询解析.sql语句优化,使用读写锁(细化到行).事物隔离和多版本并发控制提高并发,完备的事务日志记录,强大的存储引擎提供高效查询(表 ...

  4. MySQL性能优化之索引设计

    作者:IT王小二 博客:https://itwxe.com 上一篇给小伙伴们讲了关于SQL查询性能优化的相关技巧,一个好的查询SQL离不开合理的索引设计.这篇小二就来唠一唠怎么合理的设计一个索引来优化 ...

  5. Mysql性能优化三:主从配置,读写分离

    大型网站为了软解大量的并发访问,除了在网站实现分布式负载均衡,远远不够.到了数据业务层.数据访问层,如果还是传统的数据结构,或者只是单单靠一台服务器扛,如此多的数据库连接操作,数据库必然会崩溃,数据丢 ...

  6. MySQL 数据库性能优化之索引优化

    接着上一篇 MySQL 数据库性能优化之表结构,这是 MySQL数据库性能优化专题 系列的第三篇文章:MySQL 数据库性能优化之索引优化 大家都知道索引对于数据访问的性能有非常关键的作用,都知道索引 ...

  7. mysql性能优化-慢查询分析、优化索引和配置 (慢查询日志,explain,profile)

    mysql性能优化-慢查询分析.优化索引和配置 (慢查询日志,explain,profile) 一.优化概述 二.查询与索引优化分析 1性能瓶颈定位 Show命令 慢查询日志 explain分析查询 ...

  8. [MySQL性能优化系列]巧用索引

    1. 普通青年的索引使用方式 假设我们有一个用户表 tb_user,内容如下: name age sex jack 22 男 rose 21 女 tom 20 男 ... ... ... 执行SQL语 ...

  9. MySQL性能优化 - 别再只会说加索引了

    MySQL性能优化 MySQL性能优化我们可以从以下四个维度考虑:硬件升级.系统配置.表结构设计.SQL语句和索引. 从成本上来说:硬件升级>系统配置>表结构设计>SQL语句及索引, ...

随机推荐

  1. 3.开始使用Spring Cloud实战微服务

                     开始使用Spring Cloud实战微服务 3.1. Spring Cloud实战前提 3.1.1. 需要的技术储备 语言方面:可以使用Java.scala.Groo ...

  2. NDK OpenGLES3.0 开发(五):FBO 离屏渲染

    什么是 FBOFBO(Frame Buffer Object)即帧缓冲区对象,实际上是一个可添加缓冲区的容器,可以为其添加纹理或渲染缓冲区对象(RBO). FBO 本身不能用于渲染,只有添加了纹理或者 ...

  3. BeanFactory和ApplicationContext的区别+部分Spring的使用

    BeanFactory和ApplicationContext的区别 ApplicationContext 方式加载:创建容器的同时 容器初始化,容器所有的bean创建完毕   Spring容器中获取一 ...

  4. 【黑马JavaSE】1_1_11_IDEA、12_方法、13_重载

    文章目录 1_1_11_01开发工具IntelliJ IDEA 1.3 创建包.查看包的目录结构 1.5 字体设置(File->Settings->Editor->Font) 1.6 ...

  5. 在Ubuntu 16.04配置VNC Server (灰屏问题解决)

      使用命令安装 sudo apt install xfce4 xfce4-goodies tightvncserver 编辑vnc启动文件,安全期间最好备份一下 mv ~/.vnc/xstartup ...

  6. 转自网络用LIBSVM进行回归预测的粗浅认识————————作者师梦

    说一说我对用LIBSVM进行回归预测的粗浅认识(整理完成于2012年5.11) 作者 :  师梦       吾本工程小硕一枚,前用matlab建模,已然完成.某日,正沾沾自喜之际,吾师曰:“汝已为之 ...

  7. [转]Cookie详解

    从事 Web 开发已有近17个月:在学以致用的工作学习里,对于不怎么使用的部分,多少有些雾里探花的窘迫感-差不多是了解一二,然而又非真切的明晰:这就使得再用的时候,总要去再搜索一番:如此颇为难受,倒不 ...

  8. Leaflet - 实现按照路径方向旋转的 Marker

    在每帧动画时设置 Marker 的 transform 属性就行,zjffun/Leaflet.MovingMarker at zjf/feature-rotate 我在这个 Fork 中实现了一下. ...

  9. 安装 redis manager

    安装文档在redis manager 的官方文档上有,这里做个笔记.官网地址:https://snapcraft.io/redis-desktop-manager 截图1: 可以选择自己的系统,根据里 ...

  10. 机器学习之K-Mean聚类算法

    知识点: # coding = utf-8 import numpy as np import pandas as pd from sklearn.cluster import KMeans &quo ...