MySQL'de UPDATE sorgularını toplulaştırmanın en etkili yolu nedir?


10

Uzun bir süre veritabanına güncellemeleri çok sayıda temizlemek gerekiyor bir uygulama yazıyorum ve nasıl sorgu optimize etmek için sıkışmış aldım. Şu anda kullanıyorum INSERT INTO ... VALUES (..), (..) ON DUPLICATE KEY UPDATE, tüm değerleri tek bir sorguda toplu olarak çalışır, ancak büyük tablolarda dayanılmaz yavaş yürütür. Asla satır eklemem gerekmiyor.

Gördüğüm diğer yaklaşımlar kullanarak güncelleme yapmak SET value = CASE WHEN...(sorguları oluşturma şeklimden dolayı üretilmesi zor olurdu ve CASEyüzlerce / binlerce anahtarın performansından emin değilim ) ve sadece çoklu birleştirilmiş güncellemeler. Bunlardan herhangi biri şu anki yöntemimden daha hızlı mı olurdu?

Bana söyleyebildiğim kadarıyla MySQL'de bunu yapmanın deyimsel ve etkili bir yolu yok. Gerçekten daha hızlı bir yol yoksa ON DUPLICATE KEY, PostgreSQL'e geçmek ve UPDATE FROMsözdizimini kullanmak buna değer mi?

Diğer öneriler de büyük beğeni topluyor!

Düzenleme: İşte sık güncellenen tablolardan biri. Alakasız oldukları için sütun adlarını kaldırdım.

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;

Bu bir test makinesinde ve üretimde değil, bu nedenle InnoDB tam olarak ayarlanmamış. INSERT FROM'un nasıl çalıştığından tam olarak emin değilim, ancak söyledikleriniz doğru görünüyor. Soruyu, istediğiniz bilgi ile güncelledi.
jli

Yanıtlar:


14

InnoDBTabloları kullandığınızdan , en belirgin optimizasyon birden çok UPDATEs'yi bir işlemde gruplandırmak olacaktır .

İle InnoDBbir işlem motoru olan, sadece için değil ödeme UPDATEkendisi değil, aynı zamanda herkes için işlemsel havai:, işlem tampon, işlem günlüğü yönetmek diske günlüğü ateş basması.

Bu fikirden mantıklı bir şekilde memnunsanız UPDATE, her seferinde 100-1000 saniyede bir deneyin ve her seferinde şu şekilde sarın :

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

Olası olumsuz yanları:

  • Bir hata tüm işlemi daraltır (ancak kodda kolayca düzeltilir)
  • 1000 UPDATEsaniyenizi biriktirmek için uzun süre bekleyebilirsiniz , böylece zaman aşımı da yapmak isteyebilirsiniz
  • Uygulama kodunuzda daha fazla karmaşıklık.
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.