MySQL INSERT Need - kayıtları milyonlarca tablolar için SELECT sorgusu

4 Cevap php

Ben 90GB + tablo optimize doğru bir adım atmak için çalışıyorum:

Old Table

Her gün masa yaklaşık kapmak. 750,000 harici bir kaynaktan kayıtları ve yeni tarih ile masaya ekler. Bu ne anlamak itibaren üç yıl boyunca devam etmektedir. Kayıtların% 97 bir sonraki günden için değişmez.

New Table

Ben eski masa (milyonlarca ve milyonlarca kayıt) geçmesi ve büyük olasılıkla oldukça dramatik tablo boyutunu azaltacaktır fazlalığını ortadan kaldırmak için çalışıyorum.

old_table

  • tarih
  • record_id
  • data_field (gerçekten çok alan, ancak örnek uğruna)

new_table_index

  • tarih
  • index_id

new_table

  • index_id
  • record_id
  • data_field

Logic as we go through each record in old_table

(record_id new_table değil) veya (record_id new_table olduğunu, ancak bunun son giriş farklı data_field vardır) varsa

new_table takın ve index_id olsun

başka

new_table_index o record_id için son giriş index_id olsun

her zaman

new_table_index içine index_id ve tarih eklemek

Bunu yapmak için en uygun yolları üzerinde herhangi bir düşünce? Hep birlikte bu koymak için MySQL ile yeterince gelişmiş değilim. PHP bir senaryo yazmaya çalıştım zaman 3GB bellek kadar kullanılan ve daha sonra başarısız oldu. Diğer öneriler veya sorgular?? Çok teşekkürler!

4 Cevap

Ben (ilk başta çok uzakta her şekilde çevirdikten sonra) PHP ve MySQL bir melez kullanarak sona erdi:

  • TÜM ÖNCEKİ GÜN PRs İÇİN ÖNCEKİ GÜN İÇİN LINK INSERT (INSERT kullanarak - SEÇ)
  • DEĞİŞTİ IF INSERT, ÖNCEKİ GÜN KARŞI PRs Karşılaştırılması (INSERT kullanarak - SEÇ)
  • (- Php foreach - GÜNCELLEME SEÇ kullanarak) YENİ GÜNCEL PRs İÇİN LINK INSERT
  • HER GÜN YENİ PRs ADD (INSERT kullanarak - SEÇ)
  • YENİ PRs İÇİN LINK INSERT (INSERT kullanarak - SEÇ)

Hala php foreach döngüsü ile bir mükemmel gerekir, ama çoğunlukla bu hile yaptı! Tüm yardım için teşekkür ederiz!

Bu kullanabilirsiniz:

new_table
    * date
    * record_id (pk)
    * data_field


INSERT INTO new_table (date,record_id,data_field)
    SELECT date, record_id, data_field FROM old_table
        ON DUPLICATE KEY UPDATE date=old_table.data, data_field=old_table.data_field;

kayıt id birincil anahtar ve bu aynı insert old_table içine insert altına eklenebilir.

bkz mySQL

Her şeyden önce, ben iki yeni tablolar oluşturmak için herhangi bir ihtiyaç olduğunu sanmıyorum. Eğer bir dizin gerekiyorsa, iyi, MySQL indeksler için ne: sadece yeni bir tablo oluşturmak ve date alanına bir dizin ayarlayın.

Basit bir komut dosyası için (otomatik artış varsayarak new_table index_id) yapmanız gerekir:

INSERT INTO new_table (date, record_id, data_field)
  SELECT
    date,
    record_id,
    data_field
  FROM
    old_table
  GROUP BY
    data_field

Bunu yapmadan önce, tüm data_field işin içinde bir dizin oluşturma düşünebilirsiniz. Bu şekilde son derece hızlı olacaktır.

Sen LastModified zaman depolayan tabloya bir sütun ekleyebilirsiniz. daha sonra bir yandan Ekle veya Update tetikleyici üzerinde şimdiki zaman bu değeri ayarlayın. Sürecini taşıma Sizin bilgileriniz, sadece son veri portu daha büyük bir LastMotified var bu kayıtları kapmak olabilir.

Eğer endeks bu yeni alan ise çok daha hızlı tüm veri alan değerlerini karşılaştırarak daha olmalıdır.

Bu kontroller on saatlik granülarite ihtiyacınız yoksa o zaman sadece bunun yerine bir datetime bir tarihi alan türü yapabilirsiniz. Alan küçük olacak, bu yüzden onlardan daha hızlı filtre olacağını bellek ve nerede kalacak.