web-dev-qa-db-ja.com

MySQL Explain:インデックスの使用、一時的な使用、filesortの使用。このクエリを改善できますか?

いくつかのルックアップテーブルとプライマリログテーブルを使用するイベント追跡システムに取り組んでいます。私が書いているレポートでは、統計を表示するオブジェクトを選択できます。インターフェイスは、重要度の低い順にすべてのオブジェクトを表示します(つまり、ヒット)。

2つのテーブルのスキーマ(少し切り詰められますが、要点はわかります):

CREATE TABLE IF NOT EXISTS `event_log` (
  `event_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(5) DEFAULT NULL,
  `object_id` int(5) DEFAULT NULL,
  `event_date` datetime DEFAULT NULL,
  PRIMARY KEY (`event_id`),
  KEY `user_id` (`user_id`),
  KEY `object_id` (`object_id`)
);

CREATE TABLE IF NOT EXISTS `lookup_event_objects` (
  `object_id` int(11) NOT NULL AUTO_INCREMENT,
  `object_desc` varchar(255) NOT NULL,
  PRIMARY KEY (`object_id`)
);

私が問題を抱えているクエリは以下のとおりです。 100エントリ以下のテーブルでは問題なく機能しますが、EXPLAINは少し心配です。

    explain SELECT 
            el.object_id, 
            leo.object_desc, 
            COUNT(el.object_id) as count_rows
        FROM 
            event_log el 
            LEFT JOIN lookup_event_objects leo ON leo.object_id = el.object_id
        GROUP BY 
            el.object_id
        ORDER BY 
            count_rows DESC,
            leo.object_desc ASC

戻り値: Using index; Using temporary; Using filesort

それで、MySQLがtemporaryfilesortにフォールバックするための私のスキーマやクエリの何が問題になっていますか?それとも、ORDER BYを使用して取得できるように最適化されていますか?

2
a coder

これが元のクエリです

SELECT 
    el.object_id, 
    leo.object_desc, 
    COUNT(el.object_id) as count_rows
FROM 
    event_log el 
    LEFT JOIN lookup_event_objects leo ON leo.object_id = el.object_id
GROUP BY 
    el.object_id
ORDER BY 
    count_rows DESC,
    leo.object_desc ASC
;

取得するのと同じくらい最適化されているように見えます

クエリを変更します

SELECT 
    el.object_id, 
    leo.object_desc, 
    SUM(ISNULL(leo.object_id)=0) as count_rows
FROM 
    event_log el 
    LEFT JOIN lookup_event_objects leo ON leo.object_id = el.object_id
GROUP BY 
    el.object_id
ORDER BY 
    count_rows DESC,
    leo.object_desc ASC
;

これにより、特にルックアップオブジェクトのないイベントログの場合、より正確なカウントが得られる可能性があります。

2
RolandoMySQLDBA