【转载】MySQL索引优化

MySQL索引优化

原文链接

  MySQL官方对索引的定义:索引是帮助MySQL高效获取数据的数据结构。索引是在存储引擎中实现的,所以每种存储引擎中的索引都不一样。如MYISAM和InnoDB存储引擎只支持BTree索引;MEMORY和HEAP储存引擎可以支持HASH和BTREE索引。

  这里仅针对常用的InnoDB存储引擎所支持的BTree索引进行介绍:

一、索引类型

先创建一个新表,用于演示索引类型

CREATE TABLE index_table (
    id BIGINT NOT NULL auto_increment COMMENT ‘主键‘,
    NAME VARCHAR (10) COMMENT ‘姓名‘,
    age INT COMMENT ‘年龄‘,
    phoneNum CHAR (11) COMMENT ‘手机号‘,
    PRIMARY KEY (id)
) ENGINE = INNODB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8;

下图是Col2为索引列,记录与B树结构的对应图,仅供参考:

1、普通索引

这是最基本的索引,没有任何限制。

------直接创建索引
create index index_name on index_table(name);

2、唯一索引

索引列的值必须唯一,可以有空值

---------直接创建唯一索引
create UNIQUE index index_phoneNum on index_table(phoneNum);

3、主键

是一种特殊的唯一索引,必须指定为 PRIMARY KEY,如我们常用的AUTO_INCREMENT自增主键

4、多列索引

也称为组合索引,就是在多个字段上联合建立一个索引

-------直接创建组合索引
create index index_union on index_table(name,age,phoneNum);

这里一个组合索引,相当于在有如下三个索引:

name;

name,age;

name,age,phoneNum;

这里或许有这样一个疑惑:为什么age或者age,phoneNum字段上没有索引。这是由于BTree索引因要遵守最左前缀原则,这个原则在后面详细展开。

二、索引优化

1、选择索引列

创建索引简单,但是在哪些列上创建索引则需要好好思考。可以考虑在where字句中出现列或者join字句中出现的列上建索引

SELECT
    age----不使用索引
FROM
    index_union
WHERE
    NAME = ‘xiaoming‘---考虑使用索引
AND phoneNum = ‘18668247687‘;---考虑使用索引

2、最左前缀原则

  联合索引(name,age,phoneNum) ,B+树是按照从左到右的顺序来建立搜索树的。如(‘张三‘,18,‘18668247652‘)来检索数据的时候,B+树会优先匹配name来确定搜索方向,name匹配成功再依次匹配age、phoneNum,最后检索到最终的数据。也就是说这种情况下是有三级索引,当name相同,查找age,age也相同时,去比较phoneNum;但是如果拿 (18,‘18668247652‘)来检索时,B+树没有拿到一级索引,根本就无法确定下一步的搜索方向。(‘张三‘,‘18668247652‘)这种场景也是一样,当name匹配成功后,没有age这个二级索引,只能在name相同的情况下,去遍历所有的phoneNum。

  B+树的数据结构决定了在使用索引的时候必须遵守最左前缀原则,在创建联合索引的时候,尽量将经常参与查询的字段放在联合索引的最左边。

3、like的使用

一般情况下不建议使用like操作,如果非使用不可的话,需要注意:like ‘%abd%‘不会使用索引,而like ‘aaa%’可以使用索引。这也是前面的最左前缀原则的一个使用场景。

4、不能使用索引说明

mysql会按照联合索引从左往右进行匹配,直到遇到范围查询,如:>,<,between,like等就停止匹配,a = 1 and b =2 and  c > 3 and d = 4,如果建立(a,b,c,d)顺序的索引,d是不会使用索引的。但如果联合索引是(a,b,d,c)的话,则a b d c都可以使用到索引,只是最终c是一个范围值。

5、order by

order by排序有两种排序方式:using filesort使用算法在内存中排序以及使用mysql的索引进行排序;我们在部分不情况下希望的是使用索引。


1

select test_index where id = 3 order by id desc;

如果ID是单列索引,则order by会使用索引


1

select test_index where id = 3 order by name desc;

如果ID是单列索引,name不是索引或者name也是单列索引,则order by不会使用索引。因为Mysql的一次查询只会从众多索引中选择一个索引,而这次查询中使用的是ID列索引,而不是name列索引。在这种场景下,如果想让order by也使用索引的话,就建立联合索引(id,name),这里需要注意最左前缀原则,不要建立这样的联合索引(name,id)。

最后需要注意mysql对排序记录的大小有限制:max_length_for_sort_data 默认为1024;也就意味着如果需要排序的数据量大于1024,则order by不会使用索引,而是使用using filesort。

分类: MYSQL

标签: 索引优化

好文要顶 关注我 收藏该文  

冬瓜蔡
关注 - 3
粉丝 - 47

+加关注

0

0

?上一篇:什么是B+Tree

posted @ 2017-07-29 11:41 冬瓜蔡 阅读(80) 评论(0) 编辑 收藏

时间: 2024-12-19 17:40:26

【转载】MySQL索引优化的相关文章

mysql索引优化

mysql 索引优化 >mysql一次查询只能使用一个索引.如果要对多个字段使用索引,建立复合索引. >越小的数据类型通常更好:越小的数据类型通常在磁盘.内存和CPU缓存中都需要更少的空间,处理起来更快. >简单的数据类型更好:整型数据比起字符,处理开销更小,因为字符串的比较更复杂.在MySQL中,应该用内置的日期和时间数据类型,而不是用字符串来存储时间:以及用整型数据类型存储IP地址. >尽量避免NULL:应该指定列为NOT NULL,除非你想存储NULL.在MySQL中,含有空

MySQL索引优化-from 高性能MYSQL

Btree: 1. 尽量使用覆盖索引, 即三星索引 2. 多列索引如果带范围的话, 后续列不会作为筛选条件 3. 多列索引应选择过滤性更好的充当前缀索引 4. 尽量按主键顺序插入, 减少页分裂, 采用自增ID在高并发情况下, 可能造成明显征用, 或者更改innodb_autoinc_lock_mode配置. Hash: 1.只有精确匹配所有列的查询才有效, 对于每行数据, 引擎都会对所有索引列计算hash码 2. 只有memory才可以支持hash索引, innodb支持自适应hash索引, 但

Mysql 索引优化分析

MySQL索引优化分析 为什么你写的sql查询慢?为什么你建的索引常失效?通过本章内容,你将学会MySQL性能下降的原因,索引的简介,索引创建的原则,explain命令的使用,以及explain输出字段的意义.助你了解索引,分析索引,使用索引,从而写出更高性能的sql语句.还在等啥子?撸起袖子就是干! 案例分析 我们先简单了解一下非关系型数据库和关系型数据库的区别. MongoDB是NoSQL中的一种.NoSQL的全称是Not only SQL,非关系型数据库.它的特点是性能高,扩张性强,模式灵

mySql索引优化分析

MySQL索引优化分析 为什么你写的sql查询慢?为什么你建的索引常失效?通过本章内容,你将学会MySQL性能下降的原因,索引的简介,索引创建的原则,explain命令的使用,以及explain输出字段的意义.助你了解索引,分析索引,使用索引,从而写出更高性能的sql语句.还在等啥子?撸起袖子就是干! 案例分析 我们先简单了解一下非关系型数据库和关系型数据库的区别.MongoDB是NoSQL中的一种.NoSQL的全称是Not only SQL,非关系型数据库.它的特点是性能高,扩张性强,模式灵活

MySQL索引优化步骤总结

在项目使用mysql过程中,随着系统的运行,发现一些慢查询,在这里总结一下mysql索引优化步骤 1.开发过程优化 开发过程中对业务表中查询sql分析sql执行计划(尤其是业务流水表),主要是查看sql执行计划,对sql进行优化. explain执行计划关键属性 select_type,possible_keys,key,rows (1) select_type 访问类型 system>const > eq_ref > ref > fulltext > ref_or_null

MySQL——索引优化实战

上篇文章中介绍了索引的基本内容,这篇文章我们继续介绍索引优化实战.在介绍索引优化实战之前,首先要介绍两个与索引相关的重要概念,这两个概念对于索引优化至关重要. 本篇文章用于测试的user表结构: 索引相关的重要概念 基数 单个列唯一键(distict_keys)的数量叫做基数. SELECT COUNT(DISTINCT name),COUNT(DISTINCT gender) FROM user; user表的总行数是5,gender 列的基数是 2,说明 gender 列里面有大量重复值,n

MySQL 索引优化原则

一.索引优化原则 1.最左前缀匹配原则,联合索引,mysql会从做向右匹配直到遇到范围查询(>.<.between.like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整. 2.=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优

[转载]MySQL索引原理与慢查询优化

好文,以防丢失,故转之,另对排版做简单优化.原文地址:http://ourmysql.com/archives/1401 索引目的 索引的目的在于提高查询效率,可以类比字典,如果要查"mysql"这个单词,我们肯定需要定位到m字母,然后从下往下找到y字母,再找到剩下的sql.如果没有索引,那么你可能需要把所有单词看一遍才能找到你想要的,如果我想找到m开头的单词呢?或者w开头的单词呢?是不是觉得如果没有索引,这个事情根本无法完成? 索引原理 除了词典,生活中随处可见索引的例子,如火车站的

Mysql 索引优化

索引的存储分类MyISAM 存储引擎的表数据和索引是自动分开存储的,各自是独一的一个文件Innodb 存储引擎的表数据和索引是存储在同一个表空间里面,但可以由多个文件构成.Mysql 目前不支持函数索引,但是能对列的前面某一部分进行索引例如 name 字段,可以只取 name 的前 4 个字符进行索引,可降低索引文件大小.Mysql> create index ind_company_name on company(name(4));说明:ind_company_name 索引名,company