【mysql数据库中索引的作用】mysql数据库中索引的利弊分析

更新时间:2019-04-28    来源:数据库相关    手机版     字体:

【www.bbyears.com--数据库相关】


索引,可以说是数据库相关优化尤其是在Query 优化中最常用的优化手段之一了,虽然如此,但索引也并非是解决query优化的圣经,不能只要发现Query 运行不够快就将where子句中的条件全部放在索引中。什么事都是适而可止,过犹不及,一起来看过究竟吧。

索引的利处

索引能够提高数据检索的效率,降低数据库的IO 成本和排序成本。在数据库中个表的某个字段创建索引,所带来的最大益处就是将该字段作为检索条件的时候 可以极大的提高检索效率,加快检索时间,降低检索过程中所需要读取的数据量。

索引不是多多益善

索引能够极大的提高数据检索效率,也能够改善排序分组操作的性能,但是我们不能忽略的 一个问题就是索引是完全独立于基础数据之外的一部分数据。假设我们在Table ta 中的Column ca 创 建了索引idx_ta_ca,那么任何更新Column ca 的操作,MySQL 都需要在更新表中Column ca 的同时, 也更新Column ca 的索引数据,调整因为更新所带来键值变化后的索引信息。而如果我们没有对 Column ca 进行索引的话,MySQL 所需要做的仅仅只是更新表中Column ca 的信息。这样,所带来的最 明显的资源消耗就是增加了更新所带来的IO 量和调整索引所致的计算量。此外,Column ca 的索引 idx_ta_ca 是需要占用存储空间的,而且随着Table ta 数据量的增长,idx_ta_ca 所占用的空间也会 不断增长。所以索引还会带来存储空间资源消耗的增长。

如何判定是否需要创建索引

较频繁的作为查询条件的字段应该创建索引;

索引正是我们减少通过索引键字段作为查询条件的Query的IO 量的最有效手段。

唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件;

唯一性太差的字段,如状态字段,类型字段等。因为mysql首先会将索引中的键值取出来与内存中存储表数据的页中的数据相比较,但是数据页中的数据的顺序和索引队列中键值的顺序并不是一致的。假如索引中的键值a先在数据页x中找到了符合的数据,然后又在数据页y中找到了符合条件的数据,这时mysql便会把数据页x销毁掉,把数据页Y读到内存中。如果这时候还有键值b,然后键值b找的数据又在数据页x上,则mysql又要把数据页x读到内存中。也就是说从索引去寻找对应的表数据的时候是随机访问的。(实际情况应该是内存中缓存了好几页的数据,应该不只一页,但是这里假定线程内存中只存在一张页表)。这样的随机访问所造成的io消耗是比全表扫描的io消耗来得大的。(还不如遍历整张表)

假如索引字段唯一性好的话,比如是唯一的,则最多只需要换一次页表。

假如索引字段唯一性差的话,需要进行的换页次数也就相应的提高了。

更新非常频繁的字段不适合创建索引;

索引中的字段被更新的时候,不仅仅需要更新表中的 数据,同时还要更新索引数据,以确保索引信息是准确的。这个问题所带来的是IO 访问量的较大 增加,不仅仅影响更新Query 的响应时间,还会影响整个存储系统的资源消耗,加大整个存储系统 的负载。当然,并不是存在更新的字段就不适合创建索引,从上面判定策略的用语上面也可以看出,是 “非常频繁”的字段。

不会出现在WHERE 子句中的字段不该创建索引;


索引给Query优化带来好处,但我们也不忽略它的憋端,可以说是利憋参半,需要根据实际应用把握好适度。

 

下面我们就以MyISAM 来谈索引。

索引是在存储引擎层实现的,而不是服务器层。因此,它们并不是标准化的,每个引擎的索引工作方式略有不同。即使多个引擎支持同样的索引,它们的实现方式也可能有所不同。下面我们针对MyISAM存储引擎谈谈最频繁使用的B-Tree索引类型。

(这种索引在 Innodb 存储引擎中被称为 Secondary Index,后面稍加介绍)

•B-Tree定义
1970年,R.Bayer和E.mccreight提出了一种适用于外查找的树,它是一种平衡的多叉树,称为B树。

主键索引和非主键索引除了叶子结点上存储的分别是PK value 和普通key value之外,结构完全一致。


•我们可以创建的一些索引类型。(MyISAM)
1) 主键索引(PRIMARY KEY)
每张表只有一个,保证数据记录集的唯一性。
2)唯一性索引
主键索引与唯一索引的唯一区别是:前者在定义时使用的关键字是PRIMARY KEY而不是UNIQUE。
3)普通索引(由关键字KEY或INDEX定义的索引)
4)全文索引(innodb不支持)(FULLTEXT)
可以在 CHAR、VARCHAR 或 TEXT 列上创建
5)多列索引(或复合索引)
根据查询的需求设置,可以完成多条件查询,尤其大数据量查询时可以大大提升查询速度。
•浅析索引优化及SQL优化
我们来看一张示意图,只是表示关系图,请注意结点上写上数据并不是代表数据实际存储位置,只是为了更直观形象。


看图说话及提问:

•图上建立了(uid,catid,day)的复合索引
•在表建立后,有了数据,MYSQL会按着你建立的索引对应数据去生成上面的结构,每一个根到叶子到根的距离都是一样的,是有序的。
•从上图可以看出如果你的uid是定值(=),catid是定值(=),day(=)是定值,是最理想状态,完全用到索引
•如果你的uid是定值,catid是定值,day是范围,也可以完全用到
•uid定值,catid范围,day是范围,则可以用到uid和catid,因为catid您使用了范围,后面的day就用不到啦,因为排好的树不能满足您的查询需求啦。
•?1—-如果uid定值,catid范围,day范围,那可以用到哪个索引,为什么呢?
•?2—-如果表中的数据更新或是新增,那么想问,上述排好序的索引会不会改变呢?
能使用B-Tree索引的查询

•匹配全名
•匹配最左前缀
•匹配范围值
•精确匹配一部分并且匹配某个范围中的另一部分。
•只访问索引的查询
局限性

•如果查找没有从索引列的最左边开始,它就没什么用处。
•不能跳过索引中的列。
•存储引擎不能优化访问任何在第一个范围条件右边的列。
我们来详细说明一些我们在写SQL时或使用索引经常会模糊的地方及要遵守的约定。

最完美的您设定的索引完全使用,而非全表扫描。

1.索引的顺序规范。
注:建立索引时的顺序非常关键,如果是复合索引,就是多列的,请一定要仔细分析业务查询,将限定查询的字段放在最前面,最常用必用的放在最前面,范围查询的字段尽量后靠。
因为索引是不能跳过索引中的列,所以一个不常用的或范围列放在前面会导致后面的索引字段无法使用。
2.索引的顺序和where条件中字段的顺序请尽量保持一致
通常mysql会调整自己where语句中查询条件字段的顺序,而不是以查询字段的顺序为准,它是进行查询优化,去选择合适的索引。
目前我的mysql 5.0.45或77中会根据索引情况去选择合适的索引使用,所以where条件用的顺序与索引并不完全相关,
但之前有些版本要求两者一致,所以我们尽量保持一致,这样符合我们业务及可读性,同样避免一些版本处理不同的问题。
当然您可以通过测试来看看执行计划进行索引分析。
3.不是索引越多越好。
索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。(上面的问题2应该知道答案了吧)
4.尽量避免NULL(根据实际情况慎重选择default NULL)
应该指定列为NOT NULL,除非你想存储NULL。www.111cn.net在MySQL中,含有空值的列很难进行查询优化,因为它们使得索引、索引的统计信息以及比较运算更加复杂。你应该用0、一个特殊的值或者一个空串代替空值。
5.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

如select  a from t where a-5>100;

如果a上有索引则用不到,会进行全表扫描;

Select  a from t where a>105;

则可以用上索引啦。
6.如若对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
7.请避免使用select * 去查询,请列出你所实际要询的字段列,不要返回任何你用不到的字段,慷慨不是好事。
说一个强制使用某索引的方法:


EXPLAIN SELECT uid
FROM tablename
FORCE INDEX ( uid_cid )
WHERE uid = 1
AND cid > 1


(自己试试吧,呵呵!)好啦,目前先说这些,都是一些归纳总结,主要就是先铺个概念,大家了解一下存储引擎,支持的索引类型,以及实际建立及使用时的注意事项。

后续如果有时间的话,会介绍查看执行计划的explain工具,以及mysql 中show 命令,你可以想show 什么就show 什么。或者是建立表时“set utf8 collate utf8_bin NOT NULL default ””这么一行有什么作用,呵呵,后续探讨。

后续也会讨论一下InnoDB中的的B+Tree索引,聚集索引等相关方面的内容,慢慢来呵呵!

本文来源:http://www.bbyears.com/aspjiaocheng/49766.html

热门标签

更多>>

本类排行