MySQL में UPDATE प्रश्नों को बैचने का सबसे कुशल तरीका क्या है?


10

मैं एक ऐसे एप्लिकेशन को लिख रहा हूं, जिसमें बड़ी संख्या में अपडेट के लिए डेटाबेस को विस्तारित अवधि के लिए फ्लश करने की आवश्यकता है, और मैं क्वेरी को ऑप्टिमाइज़ करने के तरीके पर अटक गया हूं। वर्तमान में मैं उपयोग कर रहा हूं INSERT INTO ... VALUES (..), (..) ON DUPLICATE KEY UPDATE, जो सभी मानों को एक क्वेरी में बैचने का काम करता है, लेकिन बड़े तालिकाओं पर धीरे-धीरे निष्पादित होता है। मुझे वास्तव में पंक्तियों को सम्मिलित करने की आवश्यकता नहीं है।

अन्य दृष्टिकोण जो मैंने देखे हैं वे अद्यतन करने के लिए हैं SET value = CASE WHEN...(जो कि प्रश्नों के निर्माण के तरीके के कारण उत्पन्न करना कठिन होगा, और मैं CASEसैकड़ों / हजारों कुंजियों के प्रदर्शन के बारे में निश्चित नहीं हूं ), और बस कई संक्षिप्त अद्यतन। क्या इनमें से कोई भी मेरी वर्तमान विधि से तेज़ होगा?

यह मुझे चकित करता है, जहां तक ​​मैं बता सकता हूं, MySQL में ऐसा करने के लिए कोई मुहावरेदार, कुशल तरीका नहीं है। अगर वास्तव में ऐसा कोई रास्ता नहीं है जो इससे तेज है ON DUPLICATE KEY, तो क्या पोस्टग्रेसीक्यूएल पर स्विच करने और इसके UPDATE FROMसिंटैक्स का उपयोग करने के लिए इसके लायक होगा ?

किसी भी अन्य सुझाव भी बहुत सराहना की है!

संपादित करें: यहाँ एक टेबल है जो बार-बार अपडेट की जाती है। मैंने उन्हें अप्रासंगिक होने के कारण कॉलम नाम हटा दिए हैं।

CREATE TABLE IF NOT EXISTS `table` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `a` bigint(20) unsigned NOT NULL DEFAULT '0',
  `b` bigint(20) unsigned NOT NULL DEFAULT '0',
  `c` enum('0','1','2') NOT NULL DEFAULT '0',
  `d` char(32) NOT NULL,
  -- trimmed --
  PRIMARY KEY (`id`),
  KEY `a` (`a`),
  KEY `b` (`b`),
  KEY `c` (`c`),
  KEY `d` (`d`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

यह एक परीक्षण मशीन पर है और उत्पादन पर नहीं है इसलिए InnoDB पूरी तरह से ठीक से ट्यून नहीं किया गया है। मुझे पूरी तरह से यकीन नहीं है कि INSERT FROM कैसे संचालित होता है, लेकिन आपने जो कहा है वह सही लगता है। आपके द्वारा पूछी गई जानकारी के साथ प्रश्न को अपडेट करें।
jli

जवाबों:


14

चूंकि आप InnoDBतालिकाओं का उपयोग कर रहे हैं , इसलिए सबसे स्पष्ट अनुकूलन UPDATEएक लेनदेन में कई एस समूह के लिए होगा ।

InnoDBलेन-देन इंजन होने के साथ , आप न केवल UPDATEखुद के लिए, बल्कि सभी लेन-देन ओवरहेड के लिए भी भुगतान करते हैं: लेन-देन बफ़र, लेनदेन लॉग का प्रबंधन, लॉग टू डिस्क को फ्लश करना।

यदि आप इस विचार के साथ तार्किक रूप से सहज हैं, तो UPDATEएक बार में 100-1000 सेकंड का प्रयास करें और हर बार इस तरह लिपटे:

START TRANSACTION;
UPDATE ...
UPDATE ...
UPDATE ...
UPDATE ...
COMMIT;

संभावित गिरावट:

  • एक त्रुटि पूरे लेनदेन को ध्वस्त कर देगी (लेकिन कोड में आसानी से तय हो जाएगी)
  • आप अपने 1000 UPDATEएस को जमा करने के लिए लंबे समय तक प्रतीक्षा कर सकते हैं, इसलिए आप कुछ समय समाप्त करना चाहते हैं
  • आपके एप्लिकेशन कोड पर अधिक जटिलता।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.