您的位置:首页 > 数据库 > MySQL

mysql索引问题个人总结

2016-07-15 22:39 615 查看
mysql是一个很流行的数据库,大中小公司都有使用,本人也使用了两年mysql,对性能优化这块很有兴趣,尤其是索引,一直是一种模棱两可的感觉,主要是总结的太少,学的很琐碎,故写此文来对自己做个总结。

大多数索引(不包括hash)说白了就是颗树,设置好索引等于创建了一颗包含索引列的树,随后可以根据树的性质来快速找到指定的数据,这样就避免了去一行行找数据,大大节约了查询时间。但索引也不全是好的,结合刚才说的索引会生成带有数据的树,那么在更新数据库的时候就会要去更新索引树,那也就多了一部分操作,也就会多消耗时间,多消耗存储空间。这是索引的利弊。 接下来说下我所认识的一些索引类别,这里只涉及innodb的索引。

hash索引,hash索引是根据索引列计算出一个hash值,这个值对应一个或几个值,根据hash值可以快速找出数据,但是有一个致命的缺点,因为key的值互相之间可以说是无关联的,也就说明只能用来找特定的值,如果我们要找个区间范围的值,比如说时间范围,hash索引就无能为力了。同样的,hash索引也不能用于排序,这也就说明不能避免表扫描,其次,如果是做多列hash索引,则查询时必须使用所有的索引列查询,否则无法使用hash索引。所以hash索引看似效率很高,但是限制太多,很少有使用到。

btree树,可以说是使用最多的索引。先说说聚族索引和非聚族索引。聚族索引一般来说就是我们的primary key,但是这也不是绝对的,在没有主键的时候,会使用一个唯一的非空索引列,不管选哪个都只能一个聚族索引。 下面展示了聚族索引中的记录是如何存放的。注意到,叶子页包含了行的全部数据,但是节点页只包含了索引列。



剩下的就是非聚族索引,也是btree的一种,其中有一种叫做唯一索引,其实唯一索引和普通索引基本一样,唯一的区别是,设置了唯一索引,某列或某几列的数据不能重复,否则会报错duplicatekey。

普通索引的建立主要注意要选选择性高的列,尽量建立联合索引,最好是覆盖索引,覆盖索引其实就是说索引列覆盖了所有的查询列。

建立索引主要关注3个地方,按照sql的执行顺序来说就是

1.联表查询时的关联列需要建索引,假设是左联,那右边表的关联列就需要使用索引,这样能加快on语句的速度。

2.where语句也是建立索引的关键位置,建立的原则过会再说。

3.最后就是排序时候的索引 所有的索引需要满足几个原则,最基本的就是最左匹配原则。举个栗子:idx_key(col1,col2)。这个联合索引可以应用到两种情况,用where语句举例,col1=1 and col=2或者col1=1,但是不能用col2=n这样,不能跨过第一列。

还有一个很重要的就是不要建很多索引企图利用多个索引提高速度,因为不管如何每一次只能用到一个索引,这也就牵涉到一个问题,如果你在前三个地方中的任何地方使用了不同的索引,那mysql只能使用一个,试想一下,我们通过索引很快的从where语句中过滤出一批数据,速度很快,但如果排序的时候没有使用之前的那个索引,那排序的时候就不能使用索引,用explain看到的是filesort方式而不是index,结果排序使用了很长时间而拖慢了查询速度,所以前后索引尽量保持一致最完美,但是有时候也不能做的那么周全,这时候mysql优化器会根据预估的计算时间替我们选择合适的索引。还有几个会影响索引正常使用的情况,比如说在列上做了转换或者计算,例如a+1=n,或者是使用了null类型等等,这些都会影响索引。

最后要说明一个很重要点,不要以为你掌握了索引的建立法则就一定能建立好索引,因为在不同的数据量的情况下,原本优秀的索引会变差,或者说在数据量上升后,数据分布在数据列上的比例开始变化了,可能需要调整索引顺序,还有很多时候,需要依靠经验来做出索引(传说中的DBA!)。所以DBA是很重要的,要那么容易建那还要DBA做什么呢对吧 个人总结,望大神指教!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息