2012-02-20 9 views
3

私はテーブルに〜2Mの行が含まれています。 Bツリープライマリキー(id、round)と2つの(無関係な)インデックスがあります。クエリの最適化を挿入します

私の質問は以下のとおりです。

insert into a1 
select * from cars 
where (id, round) in (select id, min(round) from cars group by id) 

上記のクエリは を実行するために〜30代がかかりますが、なぜ次のクエリ

insert into a1 
select * from cars 
where (id, round) in (select id, max(round) from cars group by id) 

は実行に永遠に取るように見えますか?私は何時間も待った。私が変更さ唯一の事は最小 - >最大

PSです:ここにテーブルを作成

CREATE TABLE `cars` (
    `id` int(11) NOT NULL, 
    `make` varchar(128) NOT NULL, 
    `miles` varchar(128) NOT NULL, 
    `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    `round` int(11) NOT NULL, 
    `location` varchar(50) DEFAULT NULL, 
    PRIMARY KEY (`id`,`round`), 
    KEY `time` (`time`), 
    KEY `make` (`make`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 
+1

サブクエリが 'id'ではなく' round'でグループ化されるのはなぜですか?その場合のidは任意であることを認識しています - そうですか? –

+0

'(id round)in(roundで車群からのselect id、min(round)) 'と'(id round)in(select id、max)の自動車からのextended select * (ラウンド)車グループからラウンド) ' – penartur

+0

申し訳ありませんが、それはidでなければなりません。 –

答えて

2

INサブクエリは、現在のMySQLクエリオプティマイザによって最適な方法で最適化されていません。

私が使用します。

INSERT INTO a1 
    SELECT c.* 
    FROM 
     cars AS c 
    JOIN 
     (SELECT id, MAX(round) AS round 
      FROM cars 
      GROUP BY id 
     ) AS m 
     ON (m.id, m.round) = (c.id, c.round) 

すでに(id, round)に持っていたインデックスはかなり速く、一度だけ(派生テーブルなど)を実行するサブクエリを行います。もう1つの方法は、INを使用して、サブクエリをcarsテーブルのすべての行に対して1回実行します(遅い理由です)。実行計画をEXPLAINで確認してください。

+0

@タオ:それは速く働いたのですか? –

0

だあなたは法「でグループ」あなたには、単一のフィールドを使用 idフィールド上の単一のインデックスを作成してください

+0

彼はすでに '(id、round)'にインデックスを持っています。これは 'GROUP BY 'によって使用できます。 –