zoukankan      html  css  js  c++  java
  • mysql多列索引优化

     “把Where条件里面的列都建上索引”,这种说法其实是非常错误的!

    这样一个查询,假设actor_id与film_id都单独建立索引 

    SELECT film_id , actor_id FROM sakila.film_actor 
    WHERE actor_id = 1 OR film_id = 1;

    在老的mysql版本中,mysql对这个查询会使用全表扫描,除非改写成下面这样

    SELECT film_id , actor_id FROM sakila.film_actor WEHRE actor_id = 1
    UNION ALL
    SELECT film_id , actor_id FROM sakila.film_actor WEHRE actor_id = 1
    AND actor_id <> 1;

    但在mysql 5.0中,查询能够同时使用这两个单列索引进行扫描,并将结果进行合并,通过Explain的Extra列可以看到这点,这种算法有3个变种:

      1.OR条件的联合(union)

      2.AND条件的相交(intersection)

      3.组合前两种情况的联合与相交

      详解具体可以参考这里

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

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

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

    所以如果在Explain中看到有索引合并,要好好检查以下查询和表的结构是否已经是最优的

    多列索引

    顾名思义,多列索引就是将多个列作为一个索引,在一个多列B-Tree索引中,索引列的顺序意味着索引首先按照最左列进行排序,然后第二列第三列等等。所以可以按照升序或者降序进行扫描,以满足精确符合列顺序的ORDER BY , GROUP BY 和 DISTINCT等子句,所以,多列索引的顺序至关重要,key(列1, 列2) 和 key(列2, 列1) 这两个多列索引很可能有巨大的性能差距

    以下面查询为栗

    SELECT * FROM payment WHERE staff_id = 2 AND customer_id = 584;

    是应该创建一个 key(staff_id, customer_id) 还是 key(customer_id, staff_id) ?可以跑一些查询来确定在这个表中值的分布情况,来确定哪个列的选择性更高

    SELECT SUM(staff_id = 2), SUM(customer_id = 584) FROM payment

    结果里,哪个列的数量更少,就代表选择性更高,那个列就应该在建立时放在多列索引的最前面、最左侧

    不过这样也有需要注意的地方,因为这个例子查询的结果非常依赖具体的值(2,584),这样会对其他条件值的查询不公平,应该结合实际情况从全局的角度来考虑

  • 相关阅读:
    Macaca初体验-Android端(Python)
    Macaca初体验-Android端(Python)
    Macaca初体验-Android端(Python)
    什么是流媒体技术
    什么是流媒体技术
    什么是流媒体技术
    什么是流媒体技术
    设备可以和人说话了 就问你怕不怕?
    设备可以和人说话了 就问你怕不怕?
    你都有什么副业?
  • 原文地址:https://www.cnblogs.com/Scissors/p/6800216.html
Copyright © 2011-2022 走看看