MYSQL 高效索引策略(未完成)

  介绍一下如何真正的发挥索引的优势

  (1)独立的列

  我们通常会看到一些查询不当的使用索引,或者是的MYSQL无法使用已有的索引。如果查询中的列不是独立的,则MYSQL就不会使用索引。“独立的列”是指索引列不能是表达式的一部分,也不能是函数的参数

  例如下面的的这个查询语句

select student_id form student where student_id+1=5;

  看一下我们就知道where中的表达式等价于actor_id=4,但是MYSQL无法自动解析这个方程式,所以我们就要优化一下这个语句,始终把索引列单独放在比较符号的一侧

  下面是另一个常见的错误

select …… where to_days(current_data)-to_days(date_col)<=10

  (2)前缀索引和索引的选择性

  有时候索引很长的字符列,会让索引变得大且慢,碰到这种情况,一种方法是模拟哈希索引列。单有时候这样子做仍然不够,那么要怎么做呢?

  通常可以把索引开始的部分字符,这样可以大大节约索引空间,从而提高索引的效率,但这样子也会降低索引的选择性。索引的选择性是指:不重复的索引值(基数)和数据包的记录总数的比值,范围从1/#T到1之间。索引的选择性越高则查询效率越高,因为选择性高的索引可以让MySQL在查找时过滤掉更多的行。唯一索引的选择性是1,这是最好的索引选择性,性能也是最好的。

  一般情况下某个列前缀的选择性也是足够高的,足以满足查询性能。对于较长的varchar类型的列,必须使用前缀索引,因为MySQL不允许索引这些列的完整长度、

  诀窍在于要选择足够长的前缀以保证较高的选择性,同时又不能太长,前缀应该足够长,以使得前缀索引的选择性接近于索引的整个列。换句话说,前缀的基数应该接近于完整列的基数

  接下来演示一下如何创建前缀索引

  

alter table student.id add key(id(7))

  以上语句的意思就是取id的前几位进行创建前缀索引

  前缀索引是一种能使索引更小、更快的有效方法,但是另一方面也有其缺点:MySQL无法使用前缀索引做排序(order by或group by),也无法使用前缀索引做覆盖扫描

  

  (3)多列索引

  很多人对多列索引的理解都不够,一个常见的错误就是为没格列创立独立的索引,或者按照错误的顺序创建多列索引。

  第一个问题:为每个列创建独立索引

create table t{
    c1 int,
    c2 int,
    c3 int,
    key(c1),
    key(c2),
    key(c3)
};

  这种索引策略,一般是因为一句话“把where条件里面的列都建上索引”。实际上这句话是非常错误的。这样一来最好的情况下也只能是一星索引,其性能比起真正最优的索引可能差几个数量级。有时如果无法设计一个三星索引,那么不如忽略掉where子句,集中精力优化索引列的顺序,或者创建一个全覆盖索引

  在多个列上建立独立的单列索引大部分情况下并不能提高MySQL的查询性能。MySQL5.0和耿勋版本引入了索引合并策略,一定程度上可以使用表上的多个单列索引来定位指定的行。更早的MySQL只能使用其中某一个单列索引,然而这个情况下没有哪一个独立的单列索引是非常有效的。

  索引合并策略有时候是一种优化的结果,但实际上更多时候说明了表上的索引建的很糟糕:

  (1)当出现服务器对多个索引做相交操作室(通常由多个AND条件),通常意味着需要一个包含所有相关列的多列索引,而不是多个独立的单列索引

  (2)当服务器需要对多个索引做联合操作室(通常有多个OR条件),通常需要好非大量的CPU和内存资源在算法的缓存、排序和合并操作上。特别是当其中有些索引的选择性不搞,需要合并扫描返回的大量数据的时候

  (3)优化器不会把这些计算到“查询成本”中,优化器只关心随机页面读取。这会使得查询的成本被“低估”,导致该执行计划还不如直接走全表扫描。这样做不但会小号更多的CPU和内存资源,还可能会影响查询的并发性,但如果是单独运行这样的查询则往往会忽略对并发性的影响。

  如果在EXPLAIN中看到索引合并,应该好好检查一下查询和表的结构,看是不是已经是最优的。也可以通过参数optimizer_switch来关闭索引合并功能,也可以使用IGNORE INDEX提示让优化器忽略掉某些索引

  

  (4)选择合适的索引列顺序

未完待续……………………

猜你喜欢

转载自www.cnblogs.com/tijie/p/10639786.html
今日推荐