浅谈索引对数据库性能的影响

来源:互联网 发布:知乎 如何评价李叫兽 编辑:程序博客网 时间:2024/04/27 22:36

大家都知道,对于数据库来说,常见的瓶颈问题多是CPU or IO过高造成的,如果能够有效的解决这两个问题,那么的确是功德可见的,那么业界现在也有很多的方式在达到这样的目的,比如:在DB层的前面加一个中间层:例如:memcached。做DB的数据缓存,然后从一定程度上减少热点数据访问的磁盘IO(这里我们暂时不去考虑FIFO,LRU,LFO的对数据的影响)、也有将数据进行分库分表存储这些技术。今天我个人浅谈下另外一个方面,索引。因为在我个人看来,对于数据库的调优(非专业DBA,错误,遗漏之处,请指点)主要有以下几点:

1、整体架构设计:对于db层的考虑(比如;上面说到的memcached、分库分表设定等技术架构的设计)

2、sql语句的优化(后续详述。比如:in、not in、group by等)

3、db表的设计(例如:尽量用not null,不要create 表的时候enable null、字段的类型选择,例如:varchar,char,int,enum等的选择原则)

4、存储引擎(例如mysql的myisam和innodb的存储引擎,在什么时候该用啥引擎)的选择、默认charset的选择。例如:mysql的latin1还是那个啥?right,UTF8.......

5、索引的使用。

OK,暂时就想到这么多。今天浅浅的谈下,索引这个“大神”

   当我们exec一条sql语句的时候,explain:sql instance:结果发现在key和extra分别为null、filesort的时候是不是就会有冲动要加索引?会?不会?恩,不会,理性。还要看下这个sql的响应时间和操作的数据量级别大小,如果数据量大,又是all scan,那的确是需要考虑下是否应加入索引啦。那么索引,索引,是不是就是简单的一个create index index_name on table_name(fields_name)就OK了呢?

   记得以前在某里面试的时候曾经提到过这个问题,那么我个人觉得,索引的确能在某些情况下帮助我们去解决一些db层的性能问题,但是并不是说它就是万能的。为什么呢?

 1、建立索引,我们是否要考虑下,该在哪个字段上建立索引(比如:是where后面的常用字段还是非)

2、OK,那就在where后面常用的字段上建嘛!~(那么,加一句:如果这个字段在where后面被函数操作了呢?)

3、OK,where后面常用字段,并且不参与函数的运算建!~(ok,那么,我该对它建什么类型的索引呢?聚集?非聚集?)

......所以我个人对于是否该建索引的问题,应该要关注以下几个问题:

1、建索引的位置。对于经常使用作为条件的字段建立索引

2、建立索引之前,查看建立之后,是否会因为本身sql语句的问题,造成索引失效

例如:select...from A where to_days(current_date)-to_days(date_col)<=10

查询date_col值离current_date十天内的数据,但是建立在date_col上的索引会失效,因为它参与了函数的运算。对吧,喵~如何修改呢?

select...from a where date_col>=date_sub(current_date,interval 10 day);这样,你建立在date_col上的索引是生效的。但是其实还是可以进一步改进,为啥呢?因为current_date会阻止查询缓存把结果缓存,此处可以用常量代替掉current_date.(对查询缓存有兴趣进一步了解的,请google下呵呵)~

3、在对索引所建的位置确定并对该字段(已建索引)参与的sql语句分析之后,那么对于索引该建立什么类型也需要分析下。众所周知,对于该列如果说重复的值很多,那么一般都推荐建位图索引,对于日期存储的字段,一般建议建立函数索引,对于不重复的字段,一般推荐聚集索引。(这里谈到聚集索引,其实在mysql里面还要跟存储引擎有点牵连,因为innodb本身来说,使用innodb的情况下,存储引擎默认使用的索引是B-TREE索引,B-TREE索引对于写多读少的业务是比较好的,否则,效果不大,所以索引其实还需要考虑下业务特点)

至于说为什么聚集索引的速度一般要比非聚集的好,这个问题大家可以google下。留个小的共同探讨的问题:)

以上为个人这段时间对mysql高性能-索引使用读后的思考,不到之处,请多多指导,谢谢