性能优化--表索引优化

先写总结:每张表的聚簇索引(主键上自动加)很珍贵,不一定要用在ID上,可将ID列改为唯一约束。将常查询的M个列中,N个可以联合保证唯一性的列作为主键(其上将默认加聚簇索引,N尽量取到最大),其余M-N个列加非聚簇索引。查询效果很好。


详细例子:

引自:http://www.csdn.net/article/2014-04-28/2819531/2

对于每个表来讲,聚集索引只有一个,利用好了,查询速度会有意想不到的提升效果。

以MySql为例,InnoDB选取聚集索引参照列的顺序是

1)如果声声明了主键(primarykey),则这个列会被做为聚集索引;

2)如果没有声明主键,则会用一个唯一且不为空的索引列做为主键,成为此表的聚集索引;

3)上面二个条件都不满足,InnoDB会自己产生一个虚拟的聚集索引。

  1. CREATETABLE`timeline_raw`(  
  2.   
  3. `rawId`bigint(20)NOTNULLAUTO_INCREMENT,  
  4.   
  5. `uid`bigint(20)DEFAULTNULL,  
  6.   
  7. `did`bigint(20)DEFAULTNULL,  
  8.   
  9. `channelId`char(1)NOTNULLDEFAULT'1'COMMENT'1:qvga;2:720p',  
  10.   
  11. `fileId`bigint(20)DEFAULTNULL,  
  12.   
  13. `sectionId`bigint(20)DEFAULTNULL,  
  14.   
  15. `headerFilePath`varchar(120)DEFAULTNULL,  
  16.   
  17. `startTime`bigint(20)DEFAULTNULL,  
  18.   
  19. `endTime`bigint(20)DEFAULTNULL,  
  20.   
  21. `updateTime`datetimeDEFAULTNULL,  
  22.   
  23. `createTime`datetimeDEFAULTNULL,  
  24.   
  25. PRIMARYKEY(`rawId`),  
  26.   
  27. KEY`index_uid_did_startTime`(`uid`,`did`,`startTime`)USINGBTREE,  
  28.   
  29. KEY`index_uid_did_endTime`(`uid`,`did`,`endTime`)USINGBTREE,  
  30.   
  31. KEY`index_time`(`startTime`)USINGBTREE,  
  32.   
  33. KEY`index_uid_did_fileId`(`uid`,`did`,`sectionId`)USINGBTREE,  
  34.   
  35. KEY`index_sectionId`(`sectionId`)  
  36.   
  37. )ENGINE=InnoDBAUTO_INCREMENT=1DEFAULTCHARSET=utf8  

这个表有四个索引:主键rawId、sectionId、`uid`,`did`、startTime。

项目的iBatis2中有这样一条查询语句:

  1. <selectid="getRawFileList"parameterClass="java.util.HashMap"resultClass="com.defonds.mysql.raw.entity.TimelineRaw">  
  2.   
  3. SELECT*FROMtimeline_raw_  
  4.   
  5. WHEREuid=#uid#  
  6.   
  7. ANDdid=#did#  
  8.   
  9. ANDchannelId=#channelId#  
  10.   
  11. <isNotNullproperty="sectionId">ANDsectionId=#sectionId#</isNotNull>  
  12.   
  13. AND  
  14.   
  15. (  
  16.   
  17. (startTimeBETWEEN#startTime#and#endTime#)  
  18.   
  19. OR  
  20.   
  21. (endTimeBETWEEN#startTime#and#endTime#)  
  22.   
  23. OR  
  24.   
  25. (  
  26.   
  27. <![CDATA[  
  28.   
  29. startTime<=#startTime#  
  30.   
  31. ]]>  
  32.   
  33. AND  
  34.   
  35. <![CDATA[  
  36.   
  37. endTime>=#endTime#  
  38.   
  39. ]]>  
  40.   
  41. )  
  42.   
  43. )  
  44.   
  45. ORDERBYstartTime;  
  46.   
  47. </select>  

根据实际业务向timeline_raw表注入一千万条数据,进行模拟测试,发现getRawFileList的执行平均时间为160ms以上。这是不能接受的。

考虑到实际业务中对于主键rawId查询条件甚少,我们把rawId主键索引取消掉,改为唯一约束,却把sectionId+startTime+endTime作为主键(业务上能够保证其唯一性,根据InnoDB索引规则,这个索引将成为我们新表的聚集索引)。然后把sectionId、startTime两个索引也取消掉,仅保留`uid`,`did`索引。

这样子,我们新表的索引实际上只有两个了:一个聚集索引(sectionId+startTime+endTime)一个非聚集索引(`uid`,`did`)。

再次进行模拟测试,同样的数据、数据量,同样的查询结果集,getRawFileList执行平均时间已经降到了11ms。结果是令人振奋的,不是么?



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
索引优化是数据库性能优化的重要部分,可以大幅提高查询效率。索引是一种数据结构,用于加速对中数据的查找和排序。在查询中使用索引可以避免全扫描,提高查询速度。以下是索引优化的一些技巧: 1. 确定索引类型 MySQL 支持多种索引类型,包括 B-Tree 索引、Hash 索引、Full-Text 索引等。不同的索引类型适用于不同的场景。例如,B-Tree 索引适用于范围查询,而 Hash 索引适用于等值查询。因此,在创建索引时,需要根据实际情况选择合适的索引类型。 2. 确定索引字段 索引字段是指在哪些字段上创建索引。一般来说,需要在经常用于查询的字段上创建索引。但是,创建太多的索引也会影响性能,因为每个索引都需要占用存储空间,而且在插入、更新和删除数据时也会增加额外的开销。因此,需要权衡索引的数量和存储空间的使用。 3. 索引覆盖查询 索引覆盖查询是指查询结果可以从索引中直接获取,而不需要再访问数据。这样可以避免访问数据的开销,提高查询效率。要实现索引覆盖查询,需要在查询语句中包含索引字段,并且查询语句只查询索引字段。 4. 索引列的顺序 在创建索引时,需要注意索引列的顺序。一般来说,应该把区分度高的列放在前面。区分度是指该列中不同值的数量与总行数之比。区分度越高,示该列的值越能区分不同的行,因此放在前面可以提高索引效率。 5. 索引的长度 索引的长度是指索引列中的字符数或字节数。索引的长度对查询效率有影响,因为索引长度越长,索引树的高度越高,查询时需要访问的磁盘块数也就越多。因此,需要根据实际情况选择合适的索引长度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值