SQL クエリを最適化して、実行速度を向上させようとしています。
次の2つのテーブルがあります。
CREATE TABLE IF NOT EXISTS `data` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`entry` varchar(255) NOT NULL,
`numDB` int(11) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `entry` (`entry`),
UNIQUE KEY `entry_numDB` (`entry`,`numDB`),
UNIQUE KEY `entry_numDB_id` (`id`,`entry`,`numDB`),
KEY `numDB` (`numDB`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `details` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`dataID` bigint(20) NOT NULL,
`dbID` int(11) NOT NULL,
<removed - unimportant>
PRIMARY KEY (`id`),
KEY `dataID` (`dataID`),
KEY `dbID` (`dbID`),
KEY `dataID_dbID` (`dataID`,`dbID`),
<removed - unimportant>
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
エントリ (たとえば、'abc') はテーブル データに "id = 1; entry = abc, numDB = 2" として格納され、詳細には (少なくとも) 2 つのエントリ "id = 1, dataID = 1, dbID = 4" があります。 " および "id = 2、dataID = 1、dbID = 17" ですが、同じ dataID と dbID が複数回発生する可能性があります。たとえば、"id = 3、dataID = 1、dbID = 17"、"id = 4、dataID = 1、dbID = 17"。
テーブル データのエントリ
の総数: 45.245.438 テーブルの詳細のエントリの総数: 126.608.661
ここで、data.numDB でソートされた、条件 dbID = 4 を持たないテーブル データから最初の 50 エントリを取得したいと考えています。結果のクエリは次のとおりです。
SELECT DISTINCT(data.entry), data.numDB FROM blacklists.data data INNER JOIN blacklists.details details ON details.dbID NOT IN (4) AND data.id = details.dataID ORDER BY data.numDB DESC LIMIT 50
これには(少なくとも)10分の処理時間がかかります(10分後に停止しました)。
EXPLAIN の出力は次のとおりです。
EXPLAIN SELECT DISTINCT(data.entry), data.numDB FROM blacklists.data data INNER JOIN blacklists.details details ON details.dbID NOT IN (4) AND data.id = details.dataID ORDER BY data.numDB DESC LIMIT 50
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE data index PRIMARY,entry_numDB_id entry_numDB 261 NULL 45166874 Using index; Using temporary; Using filesort
1 SIMPLE details ref dataID,dbID,dataID_dbID dataID 8 blacklists.data.id 1 Using where; Distinct
DISTINCT (または GROUP BY) を使用しないと、エントリが複数回繰り返されます。
このクエリを改善する方法はありますか? すでに多くのヘルプ ページやその他の質問とその回答を読みましたが、これらの表の解決策を見つけることができませんでした。