1

InnoDB で MySQL 5.5 を使用します。次のようなクエリがあります

    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

どこ

  • thingカーディナリティは約 25k で、そのうち 3.5k は顧客 3 に属します
  • 可能な は 12 個ありcustomer_idます

でインデックスを使用してこのクエリを実行すると、customer_id約 10 秒かかります。インデックスを削除すると、0.03 秒かかります。

これがなぜなのかわかりません。インデックスなしで説明した結果は次のとおりです。

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   

ここにインデックスがあります(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   

論理的にはそうすべきではないように思われるのに、なぜこのインデックスが物事を非常に遅くしているのかを誰かが解釈するのを手伝ってくれますか?

4

1 に答える 1

2

DB エンジンがインデックスの読み取りを決定すると、行を 1 つずつ順番に読み取ります。これにより、ディスク ページ 2 の行、ページ 4 の別の行、ページ 1 の別の行、ページ 2 の次の行などを読み取ることができます。

場合によっては、行ったり来たりすると、インデックスが役に立たなくなることがあります。逆に。

クエリ プランの生成中にテーブルの統計を収集および分析する際に DB エンジンがうまく機能しない場合、インデックスが完全に断片化されたディスク読み取りを生成することを識別できない可能性があります。これはおそらくあなたが経験していることです。

テーブルを分析して、新しい統計を収集してみてください。

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

そして、インデックスの有無にかかわらず再試行してください。

于 2013-05-03T21:28:55.217 に答える