DELETE SELECT की तुलना में इतना धीमा क्यों है, फिर DELETE id से?


12

मेरे पास एक बहुत व्यस्त InnoDB तालिका (200,000 पंक्तियाँ हैं, मुझे लगता है कि प्रति सेकंड दसियों तरह के प्रश्न हैं)। बग के कारण मुझे उनके साथ 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 (...)चयन परिणाम से आईडी को चलाना , कॉपी-पेस्ट करना, 0.02 सेकंड का समय लगा।

क्या हो रहा है? क्या कोई समझा सकता है कि हालत के साथ DELETE इतना धीमा क्यों है कि यह कई बार खत्म हो जाता है, लेकिन SELECT करना और फिर आईडी द्वारा डिलीट करना इतना तेज है?

धन्यवाद।

संपादित करें: अनुरोध के अनुसार, मैंने तालिका संरचना के साथ-साथ कुछ explainपरिणाम भी पोस्ट किए । मुझे यह भी ध्यान रखना चाहिए कि इस तालिका का संदर्भ देने वाली कोई विदेशी कुंजी नहीं है।

हालाँकि, स्थिति मुझे सीधी लगती है: मेरे पास एक अनइंडेक्स फ़ील्ड है जिसका मैं चयन कर रहा हूँ। इसके लिए पूरी तालिका को स्कैन करने की आवश्यकता होती है, लेकिन यह बहुत बड़ी नहीं है। 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)

2
मुझे लगता है कि तुम बिल्कुल एक पोस्ट करना चाहिए SHOW CREATE TABLEऔर शायद एक EXPLAIN...भी।
रादु मर्ज़िया

@SoboLAN वास्तव में? ऐसा लगता है कि यह एक सरल परिदृश्य है। मैंने सवाल अपडेट किया।
इसकी जद

हाँ, लेकिन .... आप पहले स्थान पर सही थे। यदि क्षेत्र emailएकतरफा है, तो दोनों को DELETEऔर SELECTसमान रूप से धीमा काम करना चाहिए। या: आप कहते हैं कि मेज पर बहुत जोर दिया गया है। हो सकता है कि जब आपने अपना पहला प्रयास किया DELETEथा, तो उन पंक्तियों पर वास्तव में लंबे समय तक लेनदेन करने वाला कोई और था ...
रादू मुराज़े

DELETE FROM ThreadNotification2 WHERE email='invalid address';शायद एक और व्याख्या भी मदद करेगा ...
pconcepcion

@pconcepcion यदि आप लिखते हैं EXPLAIN DELETE FROM...., तो यह काम नहीं करेगा। मैं जो जानता हूं, वह केवल SELECTs पर काम करता है ।
राडू मुराज़े

जवाबों:


6

यदि क्षेत्र emailएकतरफा है, तो दोनों को DELETEऔर SELECTसमान रूप से धीमा काम करना चाहिए।

एकमात्र संभावना जिसके बारे में मैं सोच सकता हूं, वह है: आप कहते हैं कि मेज पर भारी पहुंच है। हो सकता है कि जब आप निष्पादित करने का प्रयास कर रहे थे तो किसी और व्यक्ति ने बहुत लंबा लेन-देन किया (प्रत्यक्ष या अप्रत्यक्ष रूप से उन विशिष्ट पंक्तियों को मिलाकर) DELETE

मुझे लगता है कि शायद आपको वहां कुछ नकली पंक्तियाँ डालनी चाहिए और उन्हें हटाने की कोशिश करनी चाहिए। ऐसा 2 या 3 बार करें। यदि की अवधि में कोई बड़ा अंतर है DELETE, तो डीबी लोड शायद यही कारण है।

पुनश्च: ऐसा केवल तभी करें जब लोग उन नकली पंक्तियों से नाराज नहीं होंगे: डी।


2
तो क्या आपका जवाब "मुझे नहीं पता क्यों"?
पचेरियर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.