私はかなり忙しいInnoDBテーブルを持っています(200,000行、1秒あたり数十のクエリのようなものだと思います)。バグが原因で、(同じ)無効なメールアドレスが含まれる14行を取得し、それらを削除したいと考えました。
私は単純にしようとしたDELETE FROM table WHERE email='invalid address'
と、約50秒後に「ロック待ちタイムアウトを超えて」しまいました。行の列にはインデックスが付けられていないため、これは驚くべきことではありません。
しかし、私はそうしSELECT id FROM table WHERE email='invalid address'
、それは1.25秒かかりました。実行DELETE FROM table WHERE id in (...)
、コピー、貼り付けSELECTの結果から、IDSは、0.02秒を要しました。
何が起こっている?条件付きのDELETEが非常に遅いためタイムアウトする理由を誰かが説明できますか?
ありがとう。
編集:リクエストに応じて、テーブル構造といくつかのexplain
結果を投稿しました。また、このテーブルを参照する外部キーがないことにも注意してください。
しかし、状況は私には簡単に思えます。私が選択しているインデックスのないフィールドがあります。これにはテーブル全体をスキャンする必要がありますが、それほど大きくありません。id
は主キーであるため、IDによる削除は非常に高速です。
mysql> show create table ThreadNotification2 \G
*************************** 1. row ***************************
Table: ThreadNotification2
Create Table: CREATE TABLE `ThreadNotification2` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`alertId` bigint(20) DEFAULT NULL,
`day` int(11) NOT NULL,
`frequency` int(11) DEFAULT NULL,
`hour` int(11) NOT NULL,
`email` varchar(255) DEFAULT NULL,
`highlightedTitle` longtext,
`newReplies` bit(1) NOT NULL,
`numReplies` int(11) NOT NULL,
`postUrl` longtext,
`sendTime` datetime DEFAULT NULL,
`sent` bit(1) NOT NULL,
`snippet` longtext,
`label_id` bigint(20) DEFAULT NULL,
`organization_id` bigint(20) DEFAULT NULL,
`threadEntity_hash` varchar(255) DEFAULT NULL,
`user_uid` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK3991E9D279251FE` (`organization_id`),
KEY `FK3991E9D35FC0C96` (`label_id`),
KEY `FK3991E9D3FFC22CB` (`user_uid`),
KEY `FK3991E9D5376B351` (`threadEntity_hash`),
KEY `scheduleSentReplies` (`day`,`frequency`,`hour`,`sent`,`numReplies`),
KEY `sendTime` (`sendTime`),
CONSTRAINT `FK3991E9D279251FE` FOREIGN KEY (`organization_id`) REFERENCES `Organization` (`id`),
CONSTRAINT `FK3991E9D35FC0C96` FOREIGN KEY (`label_id`) REFERENCES `Label` (`id`),
CONSTRAINT `FK3991E9D3FFC22CB` FOREIGN KEY (`user_uid`) REFERENCES `User` (`uid`),
CONSTRAINT `FK3991E9D5376B351` FOREIGN KEY (`threadEntity_hash`) REFERENCES `ThreadEntity` (`hash`)
) ENGINE=InnoDB AUTO_INCREMENT=4461945 DEFAULT CHARSET=utf8
1 row in set (0.08 sec)
mysql> explain SELECT * FROM ThreadNotification2 WHERE email='invalid address';
+----+-------------+---------------------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------------+------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | ThreadNotification2 | ALL | NULL | NULL | NULL | NULL | 197414 | Using where |
+----+-------------+---------------------+------+---------------+------+---------+------+--------+-------------+
1 row in set (0.03 sec)
mysql> explain select * from ThreadNotification2 where id in (3940042,3940237,3941132,3941255,3941362,3942535,3943064,3944134,3944228,3948122,3953081,3957876,3963849,3966951);
+----+-------------+---------------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | ThreadNotification2 | range | PRIMARY | PRIMARY | 8 | NULL | 14 | Using where |
+----+-------------+---------------------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql> delete from ThreadNotification2 where email='invalid address';
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> select id from ThreadNotification2 where email='invalid address';
+---------+
| id |
+---------+
| 3940042 |
| 3940237 |
| 3941132 |
| 3941255 |
| 3941362 |
| 3942535 |
| 3943064 |
| 3944134 |
| 3944228 |
| 3948122 |
| 3953081 |
| 3957876 |
| 3963849 |
| 3966951 |
+---------+
14 rows in set (1.25 sec)
mysql> delete from ThreadNotification2 where id in (3940042,3940237,3941132,3941255,3941362,3942535,3943064,3944134,3944228,3948122,3953081,3957876,3963849,3966951);
Query OK, 14 rows affected (0.02 sec)
email
インデックスを使用しないされ、その後、両方のDELETE
とSELECT
同じようにゆっくりと動作するはずです。または:あなたは、テーブルが頻繁にクエリされると言います。あなたが最初にしようとしたときに多分DELETE
それらの行に本当に長いトランザクションを実行している他の誰かが...あった
DELETE FROM ThreadNotification2 WHERE email='invalid address';
も役立つかもしれません
EXPLAIN DELETE FROM....
、動作しません。私が知っていることから、それだけで動作しSELECT
ます。
SHOW CREATE TABLE
と、おそらくEXPLAIN...
あまりにも。