1

using MySQL 5.5 with InnoDB. have a query like

    SELECT
        count(distinct a.thing_id) as new_thing_count,
        sum(b.price) as new_thing_spend
    FROM thing ii
    LEFT OUTER JOIN thing a
        ON a.customer_id = ii.customer_id
        AND a.created_at >= '2013-01-01'
        AND a.created_at <= '2013-03-31'
    JOIN whatsit b
        ON b.whatsit_id = a.original_whatsit_id
    WHERE ii.customer_id = 3

where

  • thing has a cardinality of about 25k, 3.5k of which belong to customer 3
  • there are 12 possible customer_ids

Now, when I run this query with an index on customer_id, it takes about 10 seconds. When I drop the index, it takes .03 seconds.

I can't figure out why this might be. Here's the result of explain without the index:

1   SIMPLE  ii  ALL                 24937   Using where
1   SIMPLE  a   ALL                 24937   Using where; Using join buffer
1   SIMPLE  b   eq_ref  PRIMARY PRIMARY 4   db.a.original_whatsit_id    1   

here it is with the index (thing_customer)

1   SIMPLE  ii  ref thing_customer  thing_customer  4   const   3409    Using index
1   SIMPLE  a   ref thing_customer  thing_customer  4   const   3409    Using where
1   SIMPLE  b   eq_ref  PRIMARY PRIMARY 4   db.a.original_whatsit_id    1   

Can someone help me interpret why this index is slowing things down SO much when logically it doesn't seem like it should?

4

1 回答 1

2

当您的数据库引擎决定读取索引时,它会按顺序一一读取行。这可能导致它读取磁盘第 2 页中的一行,第 4 页中的另一个,第 1 页中的另一个,第 2 页中的下一个,等等。

有时,来回走动使得索引无济于事——相反。

如果数据库引擎在生成查询计划时在收集和分析表的统计信息方面做得不好,它可能无法识别索引产生完全碎片化的磁盘读取。这很可能是你正在经历的。

尝试分析表格以收集新的统计信息:

http://dev.mysql.com/doc/refman/5.5/en/analyze-table.html

然后在有和没有索引的情况下重试。

于 2013-05-03T21:28:55.217 回答