ログ エントリの表と、考えられる約 100 のログ コードの説明表があります。
CREATE TABLE `log_entries` (
`logentry_id` int(11) NOT NULL AUTO_INCREMENT,
`date` datetime NOT NULL,
`partner_id` smallint(4) NOT NULL,
`log_code` smallint(4) NOT NULL,
PRIMARY KEY (`logentry_id`),
KEY `IX_code` (`log_code`),
KEY `IX_partner_code` (`partner_id`,`log_code`)
) ENGINE=MyISAM ;
CREATE TABLE IF NOT EXISTS `log_codes` (
`log_code` smallint(4) NOT NULL DEFAULT '0',
`log_desc` varchar(255) DEFAULT NULL,
`category_overview` tinyint(1) NOT NULL DEFAULT '0',
`category_error` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`log_code`),
KEY `IX_overview_code` (`category_overview`,`log_code`),
KEY `IX_error_code` (`category_error`,`log_code`)
) ENGINE=MyISAM ;
次のクエリ (20,000 行のうち 10,000 行に一致) は 0.0034 秒で実行されます (を使用LIMIT 0,20
):
SELECT log_entries.date, log_codes.log_desc FROM log_entries
INNER JOIN log_codes ON log_codes.log_code = log_entries.log_code
WHERE log_entries.partner_id = 1 AND log_codes.category_overview = 1;
しかしORDER BY log_entries.logentry_id DESC
、もちろん必要な を追加すると、0.6 秒まで遅くなります。おそらく、log_codes テーブルで「Using temporary」が使用されているためでしょうか。インデックスを削除すると、実際にはクエリの実行が速くなりますが、それでも遅くなります (0.3 秒)。
ORDER BY を使用しないクエリの EXPLAIN 出力:
+----+-------------+-------------+------+--------- -------------------+------------------+---------------------+- --------------+------+-------------+ | | ID | select_type | テーブル | タイプ | 可能な_キー | キー | key_len | 参照 | 行 | 行 エクストラ | +----+-------------+-------------+------+--------- -------------------+------------------+---------------------+- --------------+------+-------------+ | | 1 | シンプル | ログコード | 参照 | PRIMARY,IX_overview_code | IX_overview_code | 1 | 定数 | 56 | | | | | 1 | シンプル | log_entries | 参照 | IX_code,IX_partner_code | IX_パートナー_コード | 7 | const,log_codes.log_code | 25 | where | の使用 +----+-------------+-------------+------+--------- -------------------+------------------+---------------------+- --------------+------+-------------+
ORDER BY を含む:
+----+-------------+-------------+------+--------- -------------------+------------------+---------------------+- --------------+--------------------+----------------- ----------------+ | | ID | select_type | テーブル | タイプ | 可能な_キー | キー | key_len | 参照 | 行 | 行 エクストラ | +----+-------------+-------------+------+--------- -------------------+------------------+---------------------+- --------------+--------------------+----------------- ----------------+ | | 1 | シンプル | ログコード | 参照 | PRIMARY,IX_overview_code | IX_overview_code | 1 | 定数 | 56 | 一時的な使用; ファイルソートの使用 | | | 1 | シンプル | log_entries | 参照 | IX_code,IX_partner_code | IX_パートナー_コード | 7 | const,log_codes.log_code | 25 | where | の使用 +----+-------------+-------------+------+--------- -------------------+------------------+---------------------+- --------------+--------------------+----------------- ----------------+
このクエリをより高速に実行する方法に関するヒントはありますか? 適切なログエントリを取得してソートする前にログコードを選択する必要があるため、「一時的な使用」が必要な理由がわかりませんか?
更新@Eugen Rieck:
SELECT log_entries.date, lc.log_desc FROM log_entries INNER JOIN (SELECT log_desc, log_code FROM log_codes WHERE category_overview = 1) AS lc ON lc.log_code = log_entries.log_code WHERE log_entries.partner_id = 1 ORDER BY log_entries.logentry_id; +----+-------------+-------------+------+--------- -+--------------------+---------------------+---- ---------------+------+--------------------------- ------+ | | ID | select_type | テーブル | タイプ | 可能な_キー | キー | key_len | 参照 | 行 | 行 エクストラ | +----+-------------+-------------+------+--------- -+--------------------+---------------------+---- ---------------+------+--------------------------- ------+ | | 1 | プライマリ | <派生2> | すべて | ヌル | ヌル | ヌル | ヌル | 57 | 一時的な使用; ファイルソートの使用 | | | 1 | プライマリ | log_entries | 参照 | IX_code,IX_partner_code | IX_パートナー_コード | 7 | const,lc.log_code | 25 | where | の使用 | | 2 | 派生 | ログコード | 参照 | IX_overview_code | IX_overview_code | 1 | | | 56 | | | +----+-------------+-------------+------+--------- -+--------------------+---------------------+---- ---------------+------+--------------------------- ------+
更新 @RolandoMySQLDBA :
私の元のインデックスでは、ORDER BY date DESC:
SELECT log_entries.date, log_codes.log_desc FROM (SELECT log_code,date FROM log_entries WHERE partner_id = 1) log_entries INNER JOIN (SELECT log_code,log_desc FROM log_codes WHERE category_overview = 1) log_codes USING (log_code) ORDER BY log_entries.date DESC; +----+-------------+-------------+------+--------- ------+------------------+---------+------+---- ---+---------------------------------+ | | ID | select_type | テーブル | タイプ | 可能な_キー | キー | key_len | 参照 | 行 | 行 エクストラ | +----+-------------+-------------+------+--------- ------+------------------+---------+------+---- ---+---------------------------------+ | | 1 | プライマリ | <派生3> | すべて | ヌル | ヌル | ヌル | ヌル | 57 | 一時的な使用; ファイルソートの使用 | | | 1 | プライマリ | <派生2> | すべて | ヌル | ヌル | ヌル | ヌル | 21937 | where を使用します。結合バッファーの使用 | | | 3 | 派生 | ログコード | 参照 | IX_overview_code | IX_overview_code | 1 | | | 56 | | | | | 2 | 派生 | log_entries | すべて | IX_パートナー_コード | ヌル | ヌル | ヌル | 22787 | where | の使用 +----+-------------+-------------+------+--------- ------+------------------+---------+------+---- ---+---------------------------------+
あなたのインデックスでは、順序付けはありません:
SELECT log_entries.date, log_codes.log_desc FROM (SELECT log_code,date FROM log_entries WHERE partner_id = 1) log_entries INNER JOIN (SELECT log_code,log_desc FROM log_codes WHERE category_overview = 1) log_codes USING (log_code); +----+-------------+-------------+-------+-------- ---------------+-----------------------+---------+ ------+----------------------+--------------------------------+ | | ID | select_type | テーブル | タイプ | 可能な_キー | キー | key_len | 参照 | 行 | 行 エクストラ | +----+-------------+-------------+-------+-------- ---------------+-----------------------+---------+ ------+----------------------+--------------------------------+ | | 1 | プライマリ | <派生3> | すべて | ヌル | ヌル | ヌル | ヌル | 57 | | | | | 1 | プライマリ | <派生2> | すべて | ヌル | ヌル | ヌル | ヌル | 21937 | where を使用します。結合バッファーの使用 | | | 3 | 派生 | ログコード | インデックス | IX_overview_code_desc | IX_overview_code_desc | 771 | ヌル | 80 | where を使用します。インデックスの使用 | | | 2 | 派生 | log_entries | インデックス | IX_partner_code_date | IX_partner_code_date | 15 | ヌル | 22787 | where を使用します。インデックスの使用 | +----+-------------+-------------+-------+-------- ---------------+-----------------------+---------+ ------+----------------------+--------------------------------+
インデックスを使用すると、ORDER BY date DESC:
SELECT log_entries.date, log_codes.log_desc FROM (SELECT log_code,date FROM log_entries WHERE partner_id = 1) log_entries INNER JOIN (SELECT log_code,log_desc FROM log_codes WHERE category_overview = 1) log_codes USING (log_code) ORDER BY log_entries.date DESC; +----+-------------+-------------+-------+-------- ---------------+-----------------------+---------+ ------+----------------------+----------------------------------+ | | ID | select_type | テーブル | タイプ | 可能な_キー | キー | key_len | 参照 | 行 | 行 エクストラ | +----+-------------+-------------+-------+-------- ---------------+-----------------------+---------+ ------+----------------------+----------------------------------+ | | 1 | プライマリ | <派生3> | すべて | ヌル | ヌル | ヌル | ヌル | 57 | 一時的な使用; ファイルソートの使用 | | | 1 | プライマリ | <派生2> | すべて | ヌル | ヌル | ヌル | ヌル | 21937 | where を使用します。結合バッファーの使用 | | | 3 | 派生 | ログコード | インデックス | IX_overview_code_desc | IX_overview_code_desc | 771 | ヌル | 80 | where を使用します。インデックスの使用 | | | 2 | 派生 | log_entries | インデックス | IX_partner_code_date | IX_partner_code_date | 15 | ヌル | 22787 | where を使用します。インデックスの使用 | +----+-------------+-------------+-------+-------- ---------------+-----------------------+---------+ ------+----------------------+----------------------------------+
更新 @Joe Stefanelli :
SELECT log_entries.date, log_codes.log_desc FROM log_entries INNER JOIN log_codes ON log_codes.log_code = log_entries.log_code WHERE log_entries.partner_id = 1 AND log_codes.category_overview = 1 ORDER BY date DESC; +----+-------------+-------------+------+--------- ---+-----------------+---------------------+---- ----------------------+------+-------------------- --------------------------+ | | ID | select_type | テーブル | タイプ | 可能な_キー | キー | key_len | 参照 | 行 | 行 エクストラ | +----+-------------+-------------+------+--------- ---+-----------------+---------------------+---- ----------------------+------+-------------------- --------------------------+ | | 1 | シンプル | ログコード | すべて | PRIMARY,IX_code_overview | ヌル | ヌル | ヌル | 80 | where を使用します。一時的な使用; ファイルソートの使用 | | | 1 | シンプル | log_entries | 参照 | IX_code,IX_code_partner | IX_コード_パートナー | 7 | log_codes.log_code,const | 25 | where | の使用 +----+-------------+-------------+------+--------- ---+-----------------+---------------------+---- ----------------------+------+-------------------- --------------------------+