SORU
1 Mayıs 2009, Cuma


Eşleşen satırları silmek için hızlı yolu?

Veritabanları gelince göreceli bir acemi değilim. MySQL kullanıyoruz ve şu anda bir süre çalıştırmak için almak gibi bir SQL deyimi hızlandırmak için çalışıyorum. Etrafında ÇOK benzer bir soru aradım ama bulamadım.

Hedef tablo B. eşleşen bir kimliği olan Bir tablodaki tüm satırları kaldırmak için

Şu an yapıyorum:

DELETE FROM a WHERE EXISTS (SELECT b.id FROM b WHERE b.id = a.id);

Bir tablo içinde yaklaşık 100 bin satır ve tablo b hakkında 22 k satır vardır. Sütun 'id' her iki tablo için PK.

Bu ifade yaklaşık 3 dakika test kutusu üzerinde çalıştırmak için - Pentium D, SP3, 2 GB ram, MySQL 5.0.67 XP alır. Bu bana yavaş geliyor. Belki değil, ama işleri hızlandırmak için umuyordum değil. Daha iyi/daha hızlı bir şekilde bunu yapmak için var mı?


DÜZENLEME:

Yararlı olabilecek bazı ek bilgiler. Tablo A ve B B tablo oluşturmak için aşağıdaki yaptığım gibi: aynı yapıya sahip

CREATE TABLE b LIKE a;

Tablo (ve böylece tablo b) karşı yapılan sorgularını hızlandırmak için birkaç dizinleri vardır. Yine işe DB ve hala öğrenme göreli bir acemi değilim. Bu işler nasıl bilmiyorum. Ben dizinleri de temizlenecek gibi bir etkisi var varsayalım? Ayrıca eğer hızını etkileyebilecek diğer DB ayarları olsaydı orada merak ediyordum.

Ayrıca, ANTİ DB kullanıyorum.


Burada size yardımcı olabilecek bazı ek bilgiler.

Tablo yapısı buna benzer (bu biraz dezenfekte ettim) vardır:

DROP TABLE IF EXISTS `frobozz`.`a`;
CREATE TABLE  `frobozz`.`a` (
  `id` bigint(20) unsigned NOT NULL auto_increment,
  `fk_g` varchar(30) NOT NULL,
  `h` int(10) unsigned default NULL,
  `i` longtext,
  `j` bigint(20) NOT NULL,
  `k` bigint(20) default NULL,
  `l` varchar(45) NOT NULL,
  `m` int(10) unsigned default NULL,
  `n` varchar(20) default NULL,
  `o` bigint(20) NOT NULL,
  `p` tinyint(1) NOT NULL,
  PRIMARY KEY  USING BTREE (`id`),
  KEY `idx_l` (`l`),
  KEY `idx_h` USING BTREE (`h`),
  KEY `idx_m` USING BTREE (`m`),
  KEY `idx_fk_g` USING BTREE (`fk_g`),
  KEY `fk_g_frobozz` (`id`,`fk_g`),
  CONSTRAINT `fk_g_frobozz` FOREIGN KEY (`fk_g`) REFERENCES `frotz` (`g`)
) ENGINE=InnoDB AUTO_INCREMENT=179369 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

Sorunun bir kısmı bu tablo için dizin vardır olduğunu sanıyorum. Tablo B sütun id h içerir rağmen tablo B benzer görünüyor.

Ayrıca, profil oluşturma sonuçlar aşağıdaki gibidir

starting 0.000018
checking query cache for query 0.000044
checking permissions 0.000005
Opening tables 0.000009
init 0.000019
optimizing 0.000004
executing 0.000043
end 0.000005
end 0.000002
query end 0.000003
freeing items 0.000007
logging slow query 0.000002
cleaning up 0.000002

ÇÖZÜLDÜ

Tüm cevaplar ve yorumlar için teşekkürler. Onlar kesinlikle bana sorun hakkında düşünmek lazım. Tebrik ederimdotjoebenim sorundan uzak basit soru sorarak adım için "diğer tablolar başvuru Yapın.ıd?"

Sorun, bir saklı yordam iki diğer tablolar, C güncellemek için denilen Bir tablo üzerinde DELETE TETİKLEYİCİ oldu ve D. Tablo C FK bir geri vardı.kimliği ve bazı şeyler saklı yordam kimliği ile ilgili yaptıktan sonra, deyimi vardı

DELETE FROM c WHERE c.id = theId;

Bu, deyim ve yeniden yazdı AÇIKLAR içine baktım

EXPLAIN SELECT * FROM c WHERE c.other_id = 12345;

Yani, bu ne yaptığını görebiliyordum ve bana şu bilgileri verdi:

id            1
select_type   SIMPLE
table         c
type          ALL
possible_keys NULL
key           NULL
key_len       NULL
ref           NULL
rows          2633
Extra         using where

Bunu yapmak için acı verici bir işlem olduğunu ve sorun olduğunu 22500 kere (veri siliniyor verilen kümesi için) adını alacak olduğu söyledi. Bu other_id sütun üzerinde bir DİZİN oluşturdum ve İZAH tekrar araştırdık sonra, var:

id            1
select_type   SIMPLE
table         c
type          ref
possible_keys Index_1
key           Index_1
key_len       8
ref           const
rows          1
Extra         

Çok daha iyi, hatta harika.

İndex_1 ve benim silmek kat kat rapor doğrultusunda ekledimmattkemp. Bu son anda benim açımdan gerçekten çok ince bir hata shoe-horning bazı ek işlevler nedeniyle oldu. Önerilen alternatif SİL en ifadeleri, SELECT/ortaya çıktıDanielaslında zaman aynı miktarda almak kadar sona erdi ve belirtildiği gibisoulmergesöz, deyim hemen hemen yapmam gereken ne dayalı inşa edebilmek için gidiyordum iyi oldu. Bu başka bir tablo için dizin C sağladım sonra, benim Siler hızlıydı.

Öldükten sonra:
İki ders bu çalışma sonucunda ortaya çıktı. İlk olarak, SQL sorguları etkisini daha iyi bir fikir almak için deyimi AÇIKLAR gücünü kaldıraç bilmiyordum açıktır. Bu acemice bir hata, kendimi bu konuda şaka yapmayacağım. Bu hatadan ders vereceğim. İkinci olarak, soruna neden olan kodu bir sonucu 'hızlı' zihniyet ve yetersiz tasarım/test bu sorun değil er gösteren yol açtı. bu işi oldu Birkaç hatırı sayılır bir test veri setleri bu yeni işlevsellik için test giriş olarak kullanmak için oluşturulan vardı, zaman ne de benim senin değil israf olurdu. DB tarafında benim test uygulama benim yanımda yer var o derinlik yoktu. Şimdi bunu geliştirmek için fırsat var.

Reference: EXPLAIN Statement

CEVAP
6 Mayıs 2009, ÇARŞAMBA


Bunu silme veri talep edebilirsiniz en pahalı işlemdir. Zaten sorgu keşfettiği gibi, sorunun kendisi değil, onların çoğu aynı yürütme planı zaten optimize edilmiş olacak.

Tüm durumlarda, Siler yavaş olduğunu anlamak zor olsa da, oldukça basit bir açıklaması var. Orada işlem depolama motorudur. Eğer sorgunuzu yarım-iptal edildi, tüm kayıtları hala eğer hiçbir şey olmamış gibi yerinde olacağı anlamına gelir. Tam bir kez, hepsi aynı anda gitmiş olacak. SİLME sırasında diğer istemci sunucuya bağlanan SİLMEK tamamlanıncaya kadar kayıtlarını göreceksiniz.

Bunu başarmak için, Bunu bir teknik MVCC (Multi Sürüm Eşzamanlılık Kontrolü) kullanır. Temel olarak yaptığı şey her bağlantının işlem ilk açıklama başladığında olduğu gibi tüm veritabanı anlık bir görünüm vermek için. Bunu başarmak için, Bunu her kayıt, DAHİLİ olarak çoklu değerler - her bir anlık görüntü alabilir. Bu Orada güveniyor biraz zaman alır - o zaman görüşürüz anlık durumuna bağlıdır nedeni de budur.

SİLME işlemi için, her sorgu ve koşullara göre tanımlanan her bir kaydı silinmek üzere işaretlenmiş. Diğer müşteriler aynı zamanda veri erişimi olabilir gibi, hemen silme atom oranı garantilemek için kendi anlık görmek zorundalar çünkü tablodan bunları kaldırmak olamaz.

Tüm kayıtları silinmek üzere işaretlendi sonra işlem başarıyla tamamlanmış olur. Ve o zaman bile SİLME işleminiz önce anlık bir değer ile çalışan tüm diğer işlemleri de sona erdi hemen önce gerçek veri sayfaları kaldırmış olamazlar.

Tüm kayıtları işlem güvenli bir şekilde kaldırılması için onları hazırlamak için yapılması gereken aslında düşününce aslında 3 dakika gerçekten o kadar yavaş değil yani. Muhtemelen "sabit disk deyimi çalışırken. çalışma duyacaksınız Bu satırları erişerek neden olur. Performansı arttırmak olabilir denemek artırmak, Bunu arabellek havuzu boyutu için sunucunuz ve denemek sınırı diğer erişim veritabanı ise SİLİN, böylece de azaltılması numarası tarihi Sürüm var, Bunu sürdürmek başına kaydı. Ek bellek ile Bunu belleğe tablo (çoğunlukla) okuma ve bazı disk arayan zaman önlemek mümkün olabilir.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • chrmoe

    chrmoe

    7 Kasım 2006
  • ItZWaffleS420

    ItZWaffleS42

    9 EYLÜL 2011
  • SignatureSeries

    SignatureSer

    24 Aralık 2006