Büyük mysql tablolarına dizin ekleme


13

Masam var

| base_schedule_line_items | CREATE TABLE base_schedule_line_items(
idint (10) imzasız NOT NULL AUTO_INCREMENT,
installmentint (10) imzasız NOT NULL,
on_datetarih NULL DEĞİL,
actual_datetarih DEFAULT NULL,
payment_typeint (11) NULL DEĞİL,
scheduled_principal_outstandingondalık (65,0) NULL DEĞİL,
scheduled_principal_dueondalık (65,0) NULL DEĞİL,
scheduled_interest_outstandingondalık (65,0) NULL DEĞİL,
scheduled_interest_dueondalık (65,0) NULL DEĞİL,
currencyint (11) NULL DEĞİL,
updated_atdatetime NOT NULL DEFAULT '2013-01-06 14:29:16',
created_atdatetime NULL DEFAULT ' 2013-01-06 14:29:16 ',
loan_base_schedule_idint (10) imzasız NOT NULL,
lending_idint (10) imzasız NOT NULL,
rescheduletinyint (1) VARSAYILAN' 0 ',
PRIMARY KEY ( id),
KEY index_base_schedule_line_items_loan_base_schedule ( loan_base_schedule_id), KEY index_bslt_spd( scheduled_principal_due),
ANAHTAR index_bslt_lending(lending_id),
Anahtar index_bslt_actualdate( actual_date),
anahtar index_bslt_spsila ( loan_base_schedule_id, scheduled_principal_due, scheduled_interest_due, actual_date),
anahtar index_bslt_ondate( on_date),
anahtar index_bslt_oa( on_date, actual_date),
anahtar index_bslt_ol( on_date, loan_base_schedule_id),
anahtar index_bslt_oli( on_date, lending_id)
) MOTOR = InnoDB'nin AUTO_INCREMENT = 30.410.126 öntanımlı karakter kümesi = UTF-8 |

Şimdi bu tabloda 30 milyon kayıt var, buna iki dizin daha eklemeliyim ve eklemesi yıllar alıyor.

alter tablosu base_schedule_line_items dizin ekle index_bslt_sla (zamanlanmış_principal_due, actual_date, lending_id);
alter tablosu base_schedule_line_items dizin ekle index_bslt_ssla (zamanlanmış_principal_due, zamanlanmış_görev_deri, borç verme_kimliği, gerçek_tarih);

Tablo boyutunu bulmak için aşağıda belirtilen sorguyu kullandım

SEÇİN tablo_adı AS "Tablolar", yuvarlak (((data_length + index_length) / 1024/1024), 2) "MB cinsinden boyut" FROM information_schema.TABLES WHERE table_schema = "my_database_name";

Sonuç şu şekilde çıktı:

base_schedule_line_items | 20.111,00

Bunu sadece veri uzunluğunu hesaplamak için kullandım ve dizin uzunluğunu dışladım

Table_name AS "Tablolar", yuvarlak (((data_length) / 1024/1024), 2) "MB cinsinden boyut" FROM information_schema.TABLES WHERE table_schema = "my_database_name";

ve sonuç şuydu

base_schedule_line_items | 9.497,00

Endeksler

ANAHTAR index_bslt_actualdate (actual_date),
anahtar index_bslt_spsila (loan_base_schedule_id, scheduled_principal_due, scheduled_interest_due, actual_date),
anahtar index_bslt_ondate (ON_DATE),
anahtar index_bslt_oa (ON_DATE, actual_date),
anahtar index_bslt_ol (ON_DATE, loan_base_schedule_id),
anahtar index_bslt_oli (ON_DATE, lending_id)

benim tarafımdan eklendi, ancak ben emin değilim ya da başka endeksler için hangi amaçla eklendi. Bu oldukça büyük bir uygulamadır. Şimdi bir select deyimi kullanarak bir rapor ayıklama yardımcı ve onları eklemek çok zor buluyorum gibi yukarıda belirtilen iki endeks eklemeniz gerekir. Herhangi bir yardım çok takdir edilecektir

Yanıtlar:


16

Büyük tabloları değiştirme etkinliği aşamalar halinde yapılır:

  1. Test DB'sinde gerekli alanlar ve dizinlerle yeni bir tablo oluşturun (sadece yapı)
  2. Varolan tablodan veri dökümü ve aynı test DB yeni oluşturulan tabloya yükleyin
  3. Şimdi kesinti sürenizi duyurun :)
  4. Tabloları yeniden adlandırarak değiştirin - RENAME table ur_db.table_name to test.temp, test.table_name to ur_db.table_name, test.temp to test.table_name;Bu, saniyenin bir kısmını alan atomik bir işlemdir.
  5. Ek kayıtları yeni oluşturulan tabloya yükleyin (boşaltma ve yükleme sonrasında gelen kayıtlar). Bu adım, duruş sürenizi azaltmak için Adım 3'ten önce de yapılabilir.
  6. Ve sisteminiz geri döndü

Birkaç not:

  1. Bilgi şemasına doğrudan bunun gibi basmanıza gerek yok, kullanmayı deneyin SHOW TABLE STATUS from db like 'table_name'
  2. Değiştirme tablosunun hızı aşağı yukarı G / Ç hızına bağlıdır. Son kez bir doğrudan değiştirme tablosu çalıştırdığımızda (yukarıdaki adımlar olmadan), 40GB + masa boyutu 4 saat sürdü. 20 GB'lık verileriniz yıllar alıyorsa, eski bazı makinelerde çalışıyorsunuz demektir.
  3. Ayrıca, index_bslt_ondate, index_base_schedule_line_items_loan_base_schedulediğer bazı dizinler gibi istenmeyen dizinlerin bırakılması, dizinlenmiş sütun olarak en soldaki sütuna sahiptir

Bu adımlardan herhangi birine ilişkin açıklamaya ihtiyacınız varsa lütfen bize bildirin.

Düzenleme: İşlemi otomatikleştirmek için basit bir python betiği https://github.com/georgecj11/hotswap_mysql_table.git


10

Uygulamanızı engellemeden dizini eklemek için pt-online-schema-change gibi bir araç kullanabilirsiniz . Temel mantık aşağıdaki gibidir:

  • yeni dizinle tablonun boş bir kopyasını oluştur
  • tabloya çarpan değişikliklerin tablonun kopyasına uygulanmasını sağlamak için mevcut tabloya tetikleyiciler ekleyin *
  • satırları eski tablodan yenisine kopyalamaya başlayın
  • kopyalama tamamlandıktan sonra tabloları değiştirin
  • eski masayı bırak

* Tabloda mevcut tetikleyiciler varsa araç çalışmaz

Değiştirme ve bırakma davranışı, araca iletilen seçeneklere göre ayarlanabilir.

Ayrıca, yabancı anahtarlarla ilgili sorunlar var, bu yüzden ne yaptığını tam olarak anlamak için aracın belgelerini okuduğunuzdan emin olun.

Ve elbette, gerekirse geri yüklemek için tablonun bir yedeğine sahip olduğunuzdan emin olmak akıllıca olacaktır.

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.