2017-12-20 48 views
0

、GROUP BYとSUMにインデックスを使用していない:私はクエリを実行しようとすると、その後MySQLは、私はちょうどでテーブルを作成したクエリ

CREATE TABLE `table_test` (
`time` date NOT NULL, 
`line_id` char(36) NOT NULL, 
`location_id` char(36) NOT NULL, 
`placement_id` char(36) NOT NULL, 
`flight_id` char(36) NOT NULL, 
`impressions` int(11) DEFAULT `0`, 
PRIMARY KEY (`time`,`line_id`,`location_id`,`placement_id`,`flight_id`), 
KEY `table_test_IDX` (`time`,`placement_id`,`line_id`,`impressions`) USING 
BTREE 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

SELECT 
    time, 
    placement_id, 
    line_id, 
    SUM(impressions) AS totalImpress 
FROM 
    table_test 
WHERE 
    time BETWEEN '2017-11-01' AND '2017-11-30' 
GROUP BY time , placement_id , line_id; 

それは常にUsing where; Using temporary; Using filesortを使用し、中この場合、クエリにはtable_test_IDXを使用します。

私はここで何が間違っていましたか?

多くの方に感謝します。

答えて

0

集計クエリの最適化のためにMySQL documentationを調べると、GROUP BYクエリを最適化する2つの方法、つまり緩やかな索引スキャンと厳密なインデックススキャンがあります。ただし、これらのスキャンのいずれかの注意点は、選択リストで使用される唯一の集計関数がMINまたはMAXであることです。 SUMを選択しているため、これらの最適化は使用できません。

WHERE句に役立つインデックスを使用すると意味があります。これは、クエリプランの早い段階で結果セットのレコードを破棄できるためです。しかし、各グループの合計を計算するためには、MySQLは残りのテーブルの各レコードに触れなければなりません。合計を得るためにこれを回避する手段はないので、これらのレコードにどのようにアクセスするかは問題になりません。

+0

あなたの答えに感謝します。しかし、私はこのオプションを使ってクエリを実行しようとすると思います: 'USE INDEX(table_test_IDX)'。クエリの時間は通常より2倍速くなります。 –

+0

はい、クエリのどの時点でインデックスが使用されていますか?オプティマイザは必ずしも正しいことを取得するとは限りません。妥当な実行時間で、かなり小さなデータセットを持っているなら、私は物事を分析しすぎることはありません。ほとんどの場合、オプティマイザはあなたよりスマートです。 –

0

あなたはUUIDを使用していると思いますか? CHAR(36)CHAR(36) CHARACTER SET asciiに変更してください。それらを `BINARY(16)にパックする方が良いでしょう。 (http://mysql.rjweb.org/doc.php/uuidを参照してください)。これにより、サイズが108から36に縮小されます。

あなたはfilesortなどを使用していますが、PRIMARYを使用していますか? EXPLAIN SELECT ...を入力してください。

さらに高速化するには、「サマリーテーブル」の構築と維持を検討してください。 (http://mysql.rjweb.org/doc.php/summarytablesを参照してください)コンボごとに(time、placement_id、line_id)のサマリーテーブルに1つの行がある場合は、GROUP BYSUMを削除することができます。 (時間を要約すると、それでも必要になるでしょう)

関連する問題