3

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) を使用しないと、エントリが複数回繰り返されます。

このクエリを改善する方法はありますか? すでに多くのヘルプ ページやその他の質問とその回答を読みましたが、これらの表の解決策を見つけることができませんでした。

4

3 に答える 3