MySQL索引及Explain及常见优化

MySQL索引设计的原则

1. 搜索的索引列,不一定是所要选择的列。换句话说,最适合索引的列是出现在WHERE 子句中的列,或连接子句中指定的列,而不是出现在SELECT 关键字后的选择列表中的列。
2. 使用惟一索引。考虑某列中值的分布。对于惟一值的列,索引的效果最好,而具有多个重复值的列,其索引效果最差。例如,存放年龄的列具有不同值,很容易区分各行。而用来记录性别的列,只含有“ M”和“F”,则对此列进行索引没有多大用处(不管搜索哪个值,都会得出大约一半的行)
3. 使用短索引。如果对串列进行索引,应该指定一个前缀长度,只要有可能就应该这样做。例如,如果有一个CHAR(200) 列,如果在前10 个或20 个字符内,多数值是惟一的,那么就不要对整个列进行索引。对前10 个或20 个字符进行索引能够节省大量索引空
间,也可能会使查询更快。较小的索引涉及的磁盘I/O 较少,较短的值比较起来更快。更为重要的是,对于较短的键值,索引高速缓存中的块能容纳更多的键值,因此,MySQL也可以在内存中容纳更多的值。这增加了找到行而不用读取索引中较多块的可能性。
(当然,应该利用一些常识。如仅用列值的第一个字符进行索引是不可能有多大好处的,因为这个索引中不会有许多不同的值。)
4. 利用最左前缀。在创建一个n 列的索引时,实际是创建了MySQL 可利用的n 个索引。多列索引可起几个索引的作用,因为可利用索引中最左边的列集来匹配行。这样的列集称为最左前缀。(这与索引一个列的前缀不同,索引一个列的前缀是利用该的前n 个字

符作为索引值。)

5. 不要过度索引。不要以为索引“越多越好”,什么东西都用索引是错的。每个额外的索引都要占用额外的磁盘空间,并降低写操作的性能,这一点我们前面已经介绍过。在修改表的内容时,索引必须进行更新,有时可能需要重构,因此,索引越多,所花的时间越长。如果有一个索引很少利用或从不使用,那么会不必要地减缓表的修改速度。此外,MySQL 在生成一个执行计划时,要考虑各个索引,这也要费时间。创建多余的索引给查询优化带来了更多的工作。索引太多,也可能会使MySQL 选择不到所要使用的最好索引。只保持所需的索引有利于查询优化。如果想给已索引的表增加索引,应该考虑所要增加的索引是否是现有多列索引的最左索引。如果是,则就不要费力去增加这个索引了,因为已经有了。

6. 考虑在列上进行的比较类型。索引可用于“ <”、“ < = ”、“ = ”、“ > =”、“ >”和BETWEEN 运算。在模式具有一个直接量前缀时,索引也用于LIKE 运算。如果只将某个列用于其他类型的运算时(如STRCMP( )),对其进行索引没有价值。

优化select

select * from pc_spu where cate_id=2;

select * from pc_spu where cate_id=2 and brand_id=2;

优化ORDER BY

SELECT * FROM pc_spu WHERE CATE_ID=2 ORDER BY BRAND_ID ASC,CATE_ID DESC;

EXPLAIN SELECT * FROM pc_spu FORCE INDEX(idx_example) WHERE cate_id=2 ORDER BY BRAND_ID ASC,CATE_ID DESC;

这个查询必须要用到该索引

CREATE INDEX idx_example

ON table1 (col1 ASC, col2 DESC, col3 ASC)  在这种情况下,以下查询可以得到优化:

SELECT col1, col2, col3 from table1  ORDER BY col1 ASC, col2 DESC, col3 ASC  和

SELECT col1, col2, col3 from example

ORDER BY col1 DESC, col2 ASC, col3 DESC

索引不用于优化在 ORDER BY 子句中具有 ASC 和 DESC 的其它任何模式的查询。例如:

SELECT col1, col2, col3 from table1  ORDER BY col1 ASC, col2 ASC, col3 ASC  不会得到优化

优化分页查询

SELECT * FROM bbs_title ORDER BY GMT_MODIFIED LIMIT 1000,10;

SELECT a.* FROM bbs_title a INNER JOIN (SELECT ID FROM bbs_title b ORDER BY b.GMT_MODIFIED LIMIT 1000,10) b ON a.ID=b.ID;

再来给GMT_MODIFIED上加上索引

COUNT查询

SELECT COUNT(*) FROM bbs_title;

SELECT COUNT(ID) FROM bbs_title;

SELECT COUNT(1) FROM bbs_title;

性能上差不多

不要用count(*),查询的时候锁定的列数多

EXPLAIN列的解释:

table:显示这一行的数据是关于哪张表的

type:这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和ALL

possible_keys:显示可能应用在这张表中的索引。如果为空,没有可能的索引。可以为相关的域从WHERE语句中选择一个合适的语句

key: 实际使用的索引。如果为NULL,则没有使用索引。很少的情况下,MYSQL会选择优化不足的索引。这种情况下,可以在SELECT语句中使用USE INDEX(indexname)来强制使用一个索引或者用IGNORE INDEX(indexname)来强制MYSQL忽略索引

key_len:使用的索引的长度。在不损失精确性的情况下,长度越短越好

ref:显示索引的哪一列被使用了,如果可能的话,是一个常数

rows:MYSQL认为必须检查的用来返回请求数据的行数

Extra:关于MYSQL如何解析查询的额外信息。坏的例子是Using temporary和Using filesort,意思MYSQL根本不能使用索引,结果是检索会很慢

extra列返回的描述的意义

Distinct:一旦MYSQL找到了与行相联合匹配的行,就不再搜索了

Not exists: MYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行,就不再搜索了

Range checked for each Record(index map:#):没有找到理想的索引,因此对于从前面表中来的每一个行组合,MYSQL检查使用哪个索引,并用它来从表中返回行。这是使用索引的最慢的连接之一

Using filesort: 看到这个的时候,查询就需要优化了。MYSQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行

Using index: 列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候

Using temporary 看到这个的时候,查询需要优化了。这里,MYSQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上

Where used 使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。如果不想返回表中的全部行,并且连接类型ALL或index,这就会发生,或者是查询有问题不同连接类型的解释(按照效率高低的顺序排序)

system 表只有一行:system表。这是const连接类型的特殊情况

const:表中的一个记录的最大值能够匹配这个查询(索引可以是主键或惟一索引)。因为只有一行,这个值实际就是常数,因为MYSQL先读这个值然后把它当做常数来对待

eq_ref:在连接中,MYSQL在查询时,从前面的表中,对每一个记录的联合都从表中读取一个记录,它在查询使用了索引为主键或惟一键的全部时使用

ref:这个连接类型只有在查询使用了不是惟一或主键的键或者是这些类型的部分(比如,利用最左边前缀)时发生。对于之前的表的每一个行联合,全部记录都将从表中读出。这个类型严重依赖于根据索引匹配的记录多少—越少越好

range:这个连接类型使用索引返回一个范围中的行,比如使用>或<查找东西时发生的情况

index: 这个连接类型对前面的表中的每一个记录联合进行完全扫描(比ALL更好,因为索引一般小于表数据)

ALL:这个连接类型对于前面的每一个记录联合进行完全扫描,这一般比较糟糕,应该尽量避免

时间: 2024-10-25 18:07:27

MySQL索引及Explain及常见优化的相关文章

mysql数据库的安装以及常见优化设置

原文:mysql数据库的安装以及常见优化设置 本文根据优才网课程整理,面向web开发者,内容以实用为主,专业DBA可以绕行. 如果你在大公司,可能有专门的DBA来做这些事情,如果你在一个小公司当架构师或者技术总监,或者你自己创业,那DBA的活你也得干了.咱们来讲一下基本的mysql安装和优化. 一: MYSQL安装和基本配置 在linux上安装,可以用包管理工具来安装,比较简单:RedHat 系列:yum -y install mysql mysql-server Debian系列:sudo a

重新学习MySQL数据库5:根据MySQL索引原理进行分析与优化

重新学习MySQL数据库5:根据MySQL索引原理进行分析与优化 一:Mysql原理与慢查询 MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓"好马配好鞍",如何能够更好的使用它,已经成为开发工程师的必修课,我们经常会从职位描述上看到诸如"精通MySQL"."SQL语句优化"."了解数据库原理"等要求.我们知道一般的应用系统,读写比例在10:1左右,而且插入

MySQL索引使用方法和性能优化

关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车.对于没有索引的表,单表查询可能几十万数据就是瓶颈,而通常大型网站单日就可能会产生几十万甚至几百万的数据,没有索引查询会变的非常缓慢.还是以WordPress来说,其多个数据表都会对经常被查询的字段添加索引,比如wp_comments表中针对5个字段设计了BTREE索引. 一个简单的对比测试 以我去年测试的数据作为一个简单示例,20多条数据源随机生成200万条

mysql explain 及常见优化手段

在工作中如果遇到慢sql通常都可以用explain进行解析. 先列一下各个列名以及含义 列名 描述 id 在一个大的查询中每一个查询关键字都对应一个id select type select关键字对应的那个查询类型 table 表名 partitions(*) 分配的分区信息 type 针对单表的访问方法 possible_keys 可能用到的索引 key 实际上使用的索引 key len 实际用到的索引长度 ref 当索引列等值查询时,与索引列进行等值匹配的对象信息 rows 预估的需要读取的

Mysql索引、explain执行计划

1.索引的使用场景 哪些情况使用索引: 1.主键自动建立唯一索引 2.频繁作为查询条件的字段应该创建索引 where 3.多表关联查询中,关联字段应该创建索引on两边都要创建索引 select * from user left join order on user.id = order.userid 4.查询中排序的字段,应该创建索引B + tree 有顺序 5.覆盖索引 好处是?不需要回表组合索引 user表 组合索引(name,age) select * from user -------

mysql索引的使用和优化

参考: http://blog.csdn.net/xluren/article/details/32746183 http://www.cnblogs.com/hustcat/archive/2009/10/28/1591648.html 关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车.对于没有索引的表,单表查询可能几十万数据就是瓶颈,而通常大型网站单日就可能会产生几十万甚至几百万的数据,没有索引查询会变

Mysql索引详解及优化(key和index区别)

MySQL索引的概念 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针.更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度. 索引分为聚簇索引和非聚簇索引两种,聚簇索引是按照数据存放的物理位置为顺序的,而非聚簇索引就不一样了:聚簇索引能提高多行检索的速度,而非聚簇索引对于单行的检索很快 要注意的是,建立太多的索引将会影响更新和插入的速度,因为它需要同样更新每个索引文件.对于一个经常需要更新和插入的表格,就没有必要为

MySQL索引简述

文章归属:http://feiyan.info/16.html,我想自己总结,但是发现此君总结的非常详细.直接搬过来了 关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车.对于没有索引的表,单表查询可能几十万数据就是瓶颈,而通常大型网站单日就可能会产生几十万甚至几百万的数据,没有索引查询会变的非常缓慢.还是以WordPress来说,其多个数据表都会对经常被查询的字段添加索引,比如wp_comments表中针对

Mysql 索引-2

关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车.对于没有索引的表,单表查询可能几十万数据就是瓶颈,而通常大型网站单日就可能会产生几十万甚至几百万的数据,没有索引查询会变的非常缓慢.还是以WordPress来说,其多个数据表都会对经常被查询的字段添加索引,比如wp_comments表中针对5个字段设计了BTREE索引. 一个简单的对比测试 以我去年测试的数据作为一个简单示例,20多条数据源随机生成200万条