0

私は巨大なテーブルを持っています:

 CREATE TABLE `messageline` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `hash` bigint(20) DEFAULT NULL,
  `quoteLevel` int(11) DEFAULT NULL,
  `messageDetails_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FK2F5B707BF7C835B8` (`messageDetails_id`),
  KEY `hash_idx` (`hash`),
  KEY `quote_level_idx` (`quoteLevel`),
  CONSTRAINT `FK2F5B707BF7C835B8` FOREIGN KEY (`messageDetails_id`) REFERENCES `messagedetails` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=401798068 DEFAULT CHARSET=utf8 COLLATE=utf8_bin

この方法で重複行を見つける必要があります。

create table foundline AS
select ml.messagedetails_id, ml.hash, ml.quotelevel
from messageline ml,
     messageline ml1
where ml1.hash = ml.hash
  and ml1.messagedetails_id!=ml.messagedetails_id

しかし、このリクエストは既に 1 日以上機能しています。これは長すぎです。数時間は大丈夫でしょう。どうすればこれをスピードアップできますか? ありがとう。

説明:

+----+-------------+-------+------+---------------+----------+---------+---------------+-----------+-------------+
| id | select_type | table | type | possible_keys | key      | key_len | ref           | rows      | Extra       |
+----+-------------+-------+------+---------------+----------+---------+---------------+-----------+-------------+
|  1 | SIMPLE      | ml    | ALL  | hash_idx      | NULL     | NULL    | NULL          | 401798409 |             |
|  1 | SIMPLE      | ml1   | ref  | hash_idx      | hash_idx | 9       | skryb.ml.hash |         1 | Using where |
+----+-------------+-------+------+---------------+----------+---------+---------------+-----------+-------------+
4

2 に答える 2

0

これを SQL だけで行う必要はありますか? このような数のレコードの場合、これを 2 つのステップに分割する方がよいでしょう。

  1. 最初に次のクエリを実行します
    
     CREATE TABLE duplicate_hashes
     SELECT * FROM (
       SELECT hash, GROUP_CONCAT(id) AS ids, COUNT(*) AS cnt,
       COUNT(DISTINCT messagedetails_id) AS cnt_message_details,
       GROUP_CONCAT(DISTINCT messagedetails_id) as messagedetails_ids
       FROM messageline GROUP BY hash ORDER BY NULL HAVING cnt > 1
     ) tmp 
     WHERE cnt > cnt_message_details
     
    これにより、ハッシュごとに重複する ID が得られます。ハッシュフィールドにインデックスがあるため、グループ化は比較的高速になります。ここで、個別のmessagedetails_id値を数えて比較することにより、異なるmessagedetails_idの要件を暗黙的に満たします。
    
     where ml1.hash = ml.hash
     and ml1.messagedetails_id!=ml.messagedetails_id
     
  2. スクリプトを使用して duplicate_hashes テーブルの各レコードを確認します
于 2013-01-21T10:25:12.913 に答える
0

このような重複を見つけることができます

SELECT messagedetails_id, COUNT(*) c
FROM messageline ml
GROUP BY messagedetails_id HAVING c > 1;

それでも長すぎる場合は、インデックス付きフィールドでリクエストを分割する条件を追加します。

WHERE messagedetails_id < 100000
于 2013-01-20T12:22:39.640 に答える