Neden DELETE, SELECT'den, sonra kimliğe göre DELETE'den daha yavaş?


12

Oldukça yoğun bir InnoDB tablo var (200.000 satır, sanırım saniyede onlarca sorgu gibi bir şey). Bir hata nedeniyle, (aynı) geçersiz e-posta adresleri olan 14 satır aldım ve bunları silmek istedim.

Ben sadece denedim DELETE FROM table WHERE email='invalid address've yaklaşık 50 saniye sonra "Kilit bekleme zaman aşımı aşıldı" var. Satır sütunu dizine alınmadığından bu çok şaşırtıcı değil.

Ancak, daha sonra yaptım SELECT id FROM table WHERE email='invalid address've bu 1,25 saniye sürdü. Çalışan DELETE FROM table WHERE id in (...), kimlikleri SELECT sonucundan kopyalayıp yapıştırma işlemi 0,02 saniye sürdü.

Ne oluyor? Birisi koşulla birlikte SİL neden zaman aşımına uğramış kadar yavaş olduğunu açıklayabilir, ancak SELECT (SEÇ) ve sonra id ile silmek bu kadar hızlı?

Teşekkürler.

DÜZENLEME: İstek üzerine, tablo yapısını ve bazı explainsonuçları gönderdim . Ayrıca, bu tabloya atıfta bulunan yabancı anahtarların olmadığını da not etmeliyim.

Ancak, durum benim için basit görünüyor: Karşı seçtiğim, sınırsız bir alanım var. Bu, tüm tabloyu taramayı gerektirir, ancak çok büyük değildir. idbirincil anahtardır, bu nedenle kimliğe göre silmek çok hızlıdır.

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)

2
Sanırım kesinlikle bir SHOW CREATE TABLEve muhtemelen bir EXPLAIN...de göndermelisiniz.
Radu Murzea

@SoboLAN gerçekten mi? Çok basit bir senaryo gibi görünüyor. Soruyu güncelledim.
itsadok

Evet ama .... ilk etapta haklıydın. Alan varsa emailAktar, o ikisi DELETEve SELECTeşit yavaş çalışması gerekir. Veya: Tablonun yoğun bir şekilde sorgulandığını söylüyorsunuz. Belki ilk denediğinizde DELETE, bu satırlarda gerçekten uzun bir işlem yapan başka biri vardı ...
Radu Murzea

DELETE FROM ThreadNotification2 WHERE email='invalid address';Belki başka bir açıklama da yardımcı olacaktır ...
pconcepcion

@pconcepcion yazarsanız EXPLAIN DELETE FROM...., çalışmaz. Bildiğim kadarıyla, sadece SELECTs üzerinde çalışır .
Radu Murzea

Yanıtlar:


6

Alan varsa emailAktar, o ikisi DELETEve SELECTeşit yavaş çalışması gerekir.

Aklıma gelen tek olasılık şudur: Tabloya yoğun bir şekilde erişildiğini söylüyorsunuz. Belki birisini yürütmeye çalışırken çok uzun bir işlem (doğrudan veya dolaylı olarak bu belirli satırları içeren) yürüttü DELETE.

Sanırım belki oraya bazı sahte satırlar ekleyip silmeye çalışmalısınız. Bunu 2 veya 3 kez yapın. Süresinde büyük bir fark varsa, DELETEbunun nedeni büyük olasılıkla DB yüküdür.

Not: Sadece insanlar bu sahte satırlardan rahatsız olmazsa yapın: D.


2
Yani cevabınız "Nedenini bilmiyorum" mu?
Pacerier
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.