MySQL milyarlarca satıra sorgu gönderebilir mi?


283

Taramaları bir MySQL veritabanında bir kütle spektrometresinden depolamayı planlıyorum ve bu miktarda veriyi depolamanın ve analiz etmenin uzaktan uygulanabilir olup olmadığını bilmek istiyorum. Performansın çevreye bağlı olarak çılgınca değiştiğini biliyorum, ancak sert bir büyüklük sırası arıyorum: sorgular 5 gün veya 5 milisaniye mi sürer?

Giriş formatı

Her giriş dosyası tek bir spektrometre çalıştırması içerir; Her çalıştırma bir dizi taramadan oluşur ve her tarama sıralı bir veri noktası dizisine sahiptir. Bir miktar meta veri var, ancak dosyanın çoğu 32 veya 64 bitlik veya kayan dizilerden oluşuyor.

Sunucu sistemi

| ---------------- + ------------------------------- |
| OS | Windows 2008 64 bit |
| MySQL versiyonu | 5.5.24 (x86_64) |
| CPU | 2x Xeon E5420 (toplam 8 çekirdek) |
| RAM | 8GB |
| SSD dosya sistemi | 500 GiB |
| HDD RAID | 12 TiB |
| ---------------- + ------------------------------- |

İhmal edilebilir işlemci süresini kullanarak sunucuda çalışan başka hizmetler de var.

Dosya istatistikleri

| ------------------ + -------------- |
| dosya sayısı | ~ 16.000 |
| toplam boyut | 1.3 TiB |
| min boyutu | 0 bayt |
| maksimum boyut | 12 GiB |
| ortalama | 800 MiB |
| ortanca | 500 MiB |
| toplam veri noktaları | ~ 200 milyar |
| ------------------ + -------------- |

Toplam veri noktası sayısı çok kaba bir tahmindir.

Önerilen şema

Ben (yani deli gibi veriler normalize) şeyler "hakkı" yapıyor olurdu böylece ve planlıyorum runsmasa, spectrabir yabancı anahtarla tablo runsve datapointsbir yabancı anahtar ile masaya spectra.

200 Milyar veri noktası sorusu

Milyonlarca satıra dokunabilecek sorgular ortaya çıkaran çoklu spektrumlar ve muhtemelen çoklu işlemler boyunca analiz edeceğim. Her şeyi düzgün bir şekilde dizine eklediğimi (başka bir soru için bir konu olan) ve yüzlerce MiB'yi ağda karıştırmaya çalışmadığımı varsayarsak, MySQL'in bunu ele alması uzaktan mümkün mü?

ilave bilgi

Tarama verileri, XML tabanlı mzML biçimindeki dosyalardan gelecektir . Bu formatın eti <binaryDataArrayList>, verilerin depolandığı öğelerdedir. Her tarama <binaryDataArray>, birlikte alındığında formun 2 boyutlu (veya daha fazla) bir dizisini oluşturan> = 2 öğeleri üretir [[123.456, 234.567, ...], ...].

Bu veriler bir kez yazılır, bu nedenle güncelleme performansı ve işlem güvenliği kaygı verici değildir.

Bir veritabanı şeması için saf planım:

runs tablo

| sütun adı | türü |
| ------------- + ------------- |
| id | İLK ANAHTAR |
| start_time | TIMESTAMP |
| adı | VARCHAR |
| ------------- + ------------- |

spectra tablo

| sütun adı | türü |
| ---------------- + ------------- |
| id | İLK ANAHTAR |
| adı | VARCHAR |
| dizin | INT |
| spectrum_type | INT |
| temsil | INT |
| run_id | YABANCI ANAHTAR |
| ---------------- + ------------- |

datapoints tablo

| sütun adı | türü |
| ------------- + ------------- |
| id | İLK ANAHTAR |
| spectrum_id | YABANCI ANAHTAR |
| mz | ÇİFT |
| num_counts | ÇİFT |
| dizin | INT |
| ------------- + ------------- |

Bu mantıklı mı?


Dolayısıyla, çıkarım yapmış olabileceğiniz gibi, ben laboratuardaki biyolog değil programcıyım, bu yüzden bilimi neredeyse gerçek bilim adamları kadar tanımıyorum.

İşte ilgileneceğim veri türünün tek bir spektrumunun (taraması) gösterimi:

Viewer ekran görüntüsü

Yazılımın amacı, zirvelerin nerede ve ne kadar önemli olduğunu bulmaktır. Bunu şimdi çözmek için özel bir yazılım paketi kullanıyoruz, ancak kendi analiz programımızı (R'de) yazmak istiyoruz, böylece haltların altında neler olup bittiğini biliyoruz. Görebildiğiniz gibi, verilerin büyük çoğunluğu ilgi çekici değildir, ancak algoritmamızın kaçırdığı potansiyel olarak yararlı verileri çıkarmak istemiyoruz. Memnun olduğumuz muhtemel zirvelerin bir listesi elimize geçtiğinde, boru hattının geri kalanı ham veri noktaları listesinden ziyade bu zirve listesini kullanacaktır. Ham veri noktalarını büyük bir blok olarak saklamanın yeterli olacağını varsayalım, böylece gerektiğinde yeniden analiz edilebilirler, ancak sadece zirveleri ayrı veri tabanı girişleri olarak tutarlar. Bu durumda, spektrum başına sadece birkaç düzine tepe olacaktır, bu yüzden çılgın ölçekleme maddeleri



8
Bu ham A / D yoklama kütle spektrometresi verisi olduğundan, veritabanında depolamak gerçekten aptalca görünüyor. Ham verilerimi alır, bırakır, işler ve işlenmiş SONUÇLARı bir veritabanında saklardım. Sonuçlar (a) her satırda bir dalga formu depolanan dalga formları, (b) kalibrasyon eğrileri gibi bu dalga formlarıyla ilişkili diğer veriler ve (c) veri tabanında veri satırları olur. Bu, tasarımınızdan milyarlarca satır şişkinlik keser. İlk analizi yeniden yapmak istediğinizde, bazı parametreleri etkili bir şekilde düzenliyor, dev bir hesaplama işlemi gerçekleştiriyor ve yeni sonuçları db'ye kaydediyorsunuz.
Warren P,

Yanıtlar:


115

İhtiyaçlarınıza pek aşina değilim ama belki de her bir veri noktasını veritabanında saklamak biraz fazladan bir öneme sahip. Neredeyse ilişkisel bir veritabanında her pikseli ayrı bir kayıt olarak saklayarak bir görüntü kütüphanesini saklama yaklaşımını kullanmak gibi görünüyor.

Genel bir kural olarak, ikili verileri veritabanlarında saklamak çoğu zaman yanlıştır. Genellikle sorunu çözmenin daha iyi bir yolu vardır. İkili verilerin ilişkisel veritabanında saklanması doğal olarak yanlış olmasa da, çoğu zaman dezavantajlar kazançlardan daha ağır basar. İlişkisel veritabanları, adından da anlaşılacağı gibi, ilişkisel verileri depolamak için en uygun yöntemdir. İkili veri ilişkisel değildir. Veritabanlarına boyut (genellikle önemli ölçüde) ekler, performansa zarar verebilir ve milyarlarca kayda değer MySQL örneği sağlama konusunda sorulara yol açabilir. İyi haber şu ki, ikili verileri depolamak için özellikle uygun veritabanları var. Bunlardan biri, her zaman kolayca görülmese de, dosya sisteminizdir! İkili dosyalarınız için basitçe bir dizin ve dosya adlandırma yapısı bulun.

Başka bir yaklaşım, veri noktalarınız (ve belki de spektrum) verileriniz için belge tabanlı bir depolama sistemi kullanmak ve işlemler için MySQL kullanmak (ya da belki de işleri diğerleriyle aynı DB'ye koymak) olacaktır.


5
İkili verileri bir veritabanında saklamak neden yanlış olarak kabul ediliyor? (Kısmen sormak, merak ediyorum çünkü aynı zamanda bunun için bir kullanım durumu düşünebildiğim için de

15
İkili verilerin ayrı ayrı değeri yoksa, benzersiz bir satır olarak kaydedilmemelidir. Görüntüdeki Pixel 500x325 ile alakasız.

1
Bu çok iyi bir nokta. Daha sonra tekrar dışarı çıkarmamız gerekebilir diye muhtemelen ham dosyaları saklamalıyız, ancak görüntülerin depolanmasına benzerlik harika bir dosya. Şimdiye kadar her bir veri noktasına erişmemize gerek olmayacak (en yüksek çıkarımı yinelememiz dışında), bu nedenle çıkarılan istatistiksel bilgileri saklamak çok daha iyi olurdu.
haxney

107

Bir keresinde çok büyük (Terabyte +) MySQL veritabanı ile çalıştım. Sahip olduğumuz en büyük masa tam anlamıyla bir milyardan fazla satırdı. Bu MySQL 5.0 kullanıyordu, bu yüzden işlerin daha iyi olabileceği olası.

İşe yaradı. MySQL, verileri çoğu zaman doğru şekilde işledi. Yine de oldukça hantaldı. (Bir terabayt veri ile altı sigma düzeyinde kullanılabilirlik istiyorsanız, MySQL'i kullanmayın. DBA'sız ve fonları sınırlı olan bir başlangıçtık.)

Sadece verileri yedeklemek ve saklamak çok zordu. Gerekirse masayı restore etmek günler alır.

10-100 milyon sıra aralığında çok sayıda masamız vardı. Masalara yapılan önemli birleşme çok zaman alıyordu ve sonsuza dek sürecekti. Bu yüzden masaları 'yürümek' için saklı yordamlar yazdık ve 'id's' aralıklarıyla birleştiğini işledik. Bu yolla bir seferde 10-100.000 satır verilerini işledik (kimliğe 1-100,000, sonra 100,001-200,000, vb.). Bu, tüm masaya katılmaktan çok daha hızlıydı.

Birincil anahtara dayanmayan çok büyük tablolarda dizinleri kullanmak da çok daha zordur. Mysql 5.0 endeksleri iki parçada depolar - endeksleri (primer endeks dışındakiler) primer anahtar değerlerine endeksler olarak kaydeder. Böylece dizine alınmış aramalar iki bölümde yapılır: İlk önce MySQL bir dizine gider ve bulması gereken birincil anahtar değerlerini çeker, daha sonra bu değerlerin nerede olduğunu bulmak için birincil anahtar dizininde ikinci bir arama yapar.

Bunun netliği, çok büyük tablolar için (1-200 Milyon artı satır) tablolara karşı indekslemenin daha kısıtlayıcı olmasıdır. Daha az sayıda, daha basit dizinlere ihtiyacınız var. Doğrudan bir dizinde bulunmayan basit seçme ifadeleri bile yapmak asla geri gelmeyebilir. Nerede cümleleri gerekir endeksler vurmak ya unut.

Fakat tüm söylenenler aslında işler yolunda gitti. MySQL'i bu çok büyük tablolarla kullanabildik, hesaplamalar yapabildik ve doğru cevapları alabildik.

200 milyar veri satırında analiz yapmaya çalışmak çok üst düzey donanım ve çok fazla el tutma ve sabır gerektirir. Verileri, geri yükleyebileceğiniz bir biçimde yedeklemeniz önemli bir iş olacaktır.

Ben katılıyorum srini.venigalla cevabı deli gibi veriler normalize burada iyi bir fikir olmayabilir. Bu kadar çok veriye sahip birden fazla tabloya katılmak, sizi bazı soruların bir daha geri gelmeyeceği anlamına gelebilecek dosya türleri riskine yol açacaktır. Basit, tamsayı tuşlarıyla denormallize etmek size daha iyi bir başarı şansı verir.

Sahip olduğumuz her şey InnoDB idi. MyISAM ve InnoDB'ye gelince: Asıl mesele ikisini karıştırmamak. Bir sunucuyu hem MySQL'in anahtarları ve diğer verileri önbelleğe alma şekli nedeniyle gerçekten optimize edemezsiniz. Bir sunucudaki tüm tablolar için birini veya diğerini seçin. MyISAM bazı hız sorunlarına yardımcı olabilir, ancak yapılması gereken genel DBA çalışmasında yardımcı olmayabilir - bu katil olabilir.


1
MySQL, endeks (...) bölümünde 5.0'tan beri çok gelişti. Şimdi nasıl davrandığını görmek ilginç olurdu.
Ring Ø

70

deli gibi verileri normalleştirmek

Deliler gibi verileri normalleştirmek bu durumda doğru strateji olmayabilir. Verileri hem Normalize formda hem de uygulamanıza çok uygun materyalize görünümler biçiminde saklayarak seçeneklerinizi açık tutun. Bu tür uygulamalarda önemli olan, anlık sorgular yazmak DEĞİLDİR. Sorgu modelleme, veri modellemeden daha önemlidir. Hedef sorgularınızla başlayın ve optimum veri modeline doğru çalışın.

Is this reasonable?

Ayrıca tüm verilerle birlikte ek bir düz masa da oluşturacağım.

run_id | spectrum_id | data_id | <data table columns..> |

Bu tabloyu tüm sorguların birincil kaynağı olarak kullanacağım. Nedeni herhangi bir birleşme yapmak zorunda kalmamaktır. Dizin oluşturmadan yapılan katılımlar sisteminizi kullanılamaz hale getirecek ve böylesine büyük dosyalar üzerinde endekslerin bulunması aynı derecede korkunç olacaktır.

Strateji, yukarıdaki tablodaki sorguyu ilk sıraya koymak, sonuçları bir geçici tabloya boşaltmak ve geçici tabloya Run ve Spectrum tablolarını aramak ve istediğiniz verileri almaktır.


Yazma ihtiyaçlarınızı vs Okuma gereksinimlerinizi analiz ettiniz mi? SQL'i hendeklemek ve standart olmayan veri depolama mekanizmalarına gitmek çok cazip olacaktır. Benim görüşüme göre, en son çare olmalı.

Yazma hızını artırmak için, İşleyici Soketi yöntemini denemek isteyebilirsiniz. Percona, hatırlarsam, Handler Socket'ı kurulum paketinde paketler. (Percona ile ilişkisi yok!)

http://yoshinorimatsunobu.blogspot.com/2010/10/using-mysql-as-nosql-story-for.html


33

Kısa cevap kalifiye bir evet - Satır sayısı arttıkça kesin şema, veri tipleri ve seçtiğiniz operasyonlar önem kazanıyor.

Verilerinizi ne kadar normalleştirdiğiniz, depolanan verilerde gerçekleştirmeyi planladığınız işlemlere bağlıdır. Özellikle 'veri puanları' tablonuz sorunlu görünüyor - herhangi bir spektrumdan n. Değilse, ayrı ayrı depolamak bir hata olabilir. Eğer veri noktalarınız tek başlarına değil, sadece kendi ilişkili spektrumları bağlamında mantıklıysa, bir PRIMARY KEY'e ihtiyacınız yoktur - spektrumun yabancı bir anahtarı ve bir 'nth' sütunu ('indeks' sütununuz?) Yeterli olacaktır. .

Yapmanız gereken tayf içi ve tayf içi işlemleri tanımlayın ve ardından bunları başarmanın en ucuz yolunu bulun. İhtiyaç duyulan her şey eşitse, denormalize edilebilir - muhtemelen operasyonlarınıza yardımcı olacak önceden hesaplanmış bazı istatistiksel meta verilerle. Tek tek veri noktalarına SQL erişimine kesinlikle ihtiyacınız varsa, her satırın boyutunu minimum alan sayısına ve mümkün olan en küçük veri türüne indirmenizi sağlar.

Şahsen yönettiğim en büyük MySQL ~ 100 milyon satırdı. Bu boyutta satırlarınızı ve böylelikle alanlarınızı sabit boyutta tutmak istersiniz - bu, MySQL'in tablodaki herhangi bir sıranın konumunu verimli şekilde hesaplamasını sağlar; bu , her sıranın sabit boyutunu çarparak (işaretçi aritmetiğini düşünün) Kesin ayrıntılar, kullanmayı planladığınız depolama motoruna bağlıdır. Eğer ondan kurtulabiliyorsanız, hız için oluşturduğu güvenilirlikten yoksun ve sizin durumunuzda yeterli olması durumunda MyISAM kullanın. VARCHAR gibi değişken boyutlu alanları CHAR (n) ile değiştirin ve okuma sorgularınızda RTRIM () kullanın.

Tablo satırlarınız sabit genişlikte olduktan sonra, MySQL'in tamsayı veri tiplerini (bazıları standart olmayan) dikkatlice değerlendirerek bayt sayısını azaltabilirsiniz . 4 bayt INT'yi 3 bayt MEDIUMINT'e dönüştürerek ekleyebileceğiniz her 1 bayt tasarruf, milyon satır başına ~ 1 MB tasarruf sağlar - daha az disk G / Ç ve daha etkili önbellekleme anlamına gelir. Kurtulabileceğiniz en küçük veri türlerini kullanın . Kayan nokta türlerini dikkatlice değerlendirin ve 8 baytlık ÇİFTLER'i 4 baytlık FLOAT'lar veya hatta <8 baytlık sabit noktalı NUMERİK'lerle değiştirip değiştiremeyeceğinizi görün . Seçtiğin şeyin seni daha sonra ısırmadığından emin olmak için testler yap.

Veri kümenizin beklenen özelliklerine ve gereken işlemlere bağlı olarak, değerlerinizin daha olağandışı kodlamalarında daha fazla tasarruf sağlanabilir (bir değerler kümesine indeks olarak kodlanabilecek beklenen desenler / tekrarlar, yalnızca anlamlı bir şekilde katkıda bulunabilecek ham veriler) meta veri ve atılma, vb.) - egzotik, sezgisel olmayan, yıkıcı optimizasyonlar ancak diğer her seçenek denendiğinde faydalı olacaktır.

En önemlisi, ne yaparsanız yapın, mükemmel şemayı seçtiğinizi varsaymayın ve kör bir şekilde 10 milyonlarca kayıt dökmeye başlayın. İyi tasarımların gelişmesi zaman alır. Büyük fakat yönetilebilir (örneğin% 1-5) test verisi oluşturun ve şemanızın doğruluğunu ve performansını doğrulayın. Farklı işlemlerin nasıl yapıldığını görün (http://dev.mysql.com/doc/refman/5.0/en/using-explain.html) ve en sık yapılan işlemleri tercih etmek için şemalarınızı dengelemenizi sağlayın.

Kısa mı dedim? Whoops. Neyse, iyi şanslar!


23

Veri noktası verilerini XML'den (çalışma zamanı ve türü gibi meta verilerin tersine) ve bir veritabanı formuna ayırmanın tek sebebi, dizilerdeki spektrumları analiz ettiğinizde - yani hepsini bulmaktır. belirli bir imzayla çalışır. Şu anda sorunlu alanınızı yalnızca siz biliyorsunuzdur, ancak bu, satır başına 1 örnekle 96kHz’de örneklenen müzikleri depolamaya benzer. Sorunun, verilerin nasıl kullanıldığından daha fazla olduğundan emin değilim. Veriler arasında sorgulama yapmak, nispi genliği The Beatles tarafından tüm şarkılardaki şarkıya 2 dakika sormakla aynı olacaktır. Yapılabilecek analiz türlerini biliyorsanız, bunları sinyaller üzerinde yapmak ve bunları meta veride çalıştırmak hakkında saklamak daha mantıklı olabilir.

Kaynak verilerinizin seyrek olup olmadığından da emin değilim. Veritabanındaki bir spektrumun yalnızca sıfır olmayan girişler içermesi tamamen mümkündür, orijinal XML ise sıfır girişler içerir ve böylece toplam satır sayınız kaynak verilerden çok daha az olabilir.

Bu nedenle, birçok soru gibi, MySQL'in modelinizi ele almasından, geriye adım atmak ve modele bakmaktan ve nasıl kullanılacağından bahsetmeden önce muhtemelen henüz performans konusunda endişelenmekten daha uygun olur.


Soru güncellemelerinizi inceledikten sonra, ikili verilerin bir BLOB olarak saklandığı veya dosyanın sadece bir göstergesinin bulunduğu bir modelin yeterli olduğunu ve veriler ilk kez belirlendiğinde önemli olan tepe noktaları hakkındaki verileri depolamak üzere modelinizi değiştirmeye çalıştığını düşünüyorum. okuyun.


18

Her biri 100 milyondan fazla tablo içeren ve her biri bir sunucuda olmak üzere, bir milyardan fazla satır olma eğiliminde olan, her biri 100 milyondan fazla tablo içeren yaklaşık 50 veritabanı sunucusuyla bir web analiz hizmeti çalıştırıyorum.

Buradaki performans iyi. Çok normalleştirilmiş bir veridir. Ancak - bunu okumakla ilgili asıl endişem bu tablolar için 4,2 milyar satır işaretinin üzerinde olacağınızdır (belki "çalışmaz" ama muhtemelen diğer ikisidir), bunun için INT yerine BIGINT kullanmanız gerekir birincil / yabancı anahtarlar.

Dizin oluşturulmuş bir sütundaki BIGINT alanlarıyla MySQL performansı INT'ye kıyasla gülünç derecede korkunç . Bunu bir kez bu büyüklükte büyüyebileceğini düşündüğüm bir masa ile yapma hatası yaptım ve bir kaç yüz milyon satıra çarptığında performans tamamen berbattı. Ham numaralarım yok ama kötü derken, Windows ME kötü demek.

Bu sütun birincil anahtardı. Biz sadece bir INT ve presto magico olarak geri dönüştürdük, performans yine iyi oldu.

O zamanlar sunucularımızın tümü Debian 5 ve MySQL 5.0 ile çalışıyordu. O zamandan beri Debian 6 ve Percona MySQL 5.5'e yükselttik, o zamandan bu yana işler düzelmiş olabilir. Ama buradaki deneyimime dayanarak, hayır, çok iyi çalışacağını sanmıyorum.


17

Çalışsa da çalışmasa da, daima tek bir yekpare depolama ortamıyla aynı problemle karşılaşırsınız: diskler yavaştır. 100 MB / s'de (medyayı döndürmek için oldukça iyi) sadece 1TB'lik bir tabloyu okumak 3 saat sürer ; Bu, herhangi bir analiz yapılmadığını veya arayışta olmadığını veya diğer gecikmelerin sizi yavaşlattığını varsayar.

Bu nedenle hemen hemen her "büyük veri" kurulumunda bir çeşit dağıtık veri deposu kullanılmaktadır. DB'nizi çalıştırmak için harika bir bilgisayar oluşturmak için 8 kat daha fazla para harcayabilirsiniz, ancak paralel olarak taranabilecek çok fazla veri varsa, yükü 8 ucuz bilgisayara dağıtmaktan hemen hemen her zaman daha iyidir.

Hadoop gibi projeler özellikle bunun gibi amaçlar için inşa edildi. Bir sürü ucuz bilgisayardan oluşan bir küme oluşturuyorsunuz, verileri hepsine dağıtıyor ve paralel olarak sorgulıyorsunuz. Bu aynı fikre dayanan yarım düzine çözümden sadece bir tanesi, ama çok popüler bir çözüm.


13

Hm ... Bu tür bir veri yapısını seçmeniz için iki neden görüyorum:

  • herhangi bir veri noktası sorgusuna karşılık herhangi bir veri noktasını gerçekten yapmanız gerekiyor
  • tüm mantığınızı SQL'de gerçekleştirmeyi düşünüyorsunuz

Şimdi, gereksinimlerinize uzunca bir göz atmanızı ve yukarıdaki varsayımlardan en az birinin doğru olduğunu doğrulamanızı öneririm. İkisi de doğruysa, işleri yavaşlatırsınız. Bu tür bir veri kümesi için, öncelikle verilere nasıl erişilmesinin beklendiğini, ne tür bir doğruluğa ihtiyacınız olduğunu vb. Bulmanızı ve sonra da veritabanınızı bunun etrafında tasarlamanızı öneririm.

Not: Veri noktası başına en az 36 + 5 bayta ihtiyaç duyacağınızı unutmayın, bu nedenle size en az 8,2 TB gerekli alan sağlayacak 200B veri noktasıyla.

PPS: Tablodaki idsütuna ihtiyacınız yoktur, muhtemelen yeterlidir ( ayrılmış bir kelime olabilir.datapointsPRIMARY KEY (spectrum_id, index)index


12

DÜZENLE:

TEK BİR DİSKTE DEPOLANMIŞ VERİLERİ İLE MYSQL'DE YAPMAYIN. Sadece tek bir ortamdan bu miktarda veri okumak saatler alacaktır. YUKARI DEĞİL, YUKARI DEĞİL.

Etkili veri analizi yapmak istiyorsanız, verilerinizi normalleştirmeniz gerekir. Burada bir çevrimiçi sistem tasarlamıyorsunuz. Sayıları ezmek istiyorsan, buna göre tasarla.

Satırın altındaki orijinal cevap.


Cevap, sorularınıza bağlı olarak değişecektir, MySQL bu iş için en iyi araç olmayabilir. “Yukarı” olarak değil, “yukarı” olarak ölçekleyebileceğiniz çözüme bakmak isteyebilirsiniz. Biraz çaba sarf etmeye istekli iseniz, belki Hadoop gibi bir Harita Azaltma çözümüne bakmalısınız.

Daha fazla geçici sorgu yapmak istiyorsanız Google’ın BigQuery çözümü sizin için uygun olabilir. Google I / O 2012'den alakalı sunum: BigQuery ile Büyük Verilerin Kırılması

Bu nedenle, çözüm bu tek seferlik bir şey olup olmadığına ve geçici sorguları makul bir şekilde desteklemek istediğinizde bağlı olacaktır.


9

Kimse bahsetmedi, benim önerim. Büyük ölçüde paylaşılan MySQL çözümlerine bir göz atın . Örneğin, bu saygın tumblr sunumunu görün .

Kavram şudur:

  • Ekstra büyük bir veritabanı yerine
  • Orijinal verilerin bir kısmını tutan birçok küçük olanı kullanın

Böylece dikey performansı iyileştirmeye çalışmak yerine yatay olarak ölçeklendirebilirsiniz. Google'ın BigTable ve GFS de depolamak ve verilerin sorgu petabayt ucuz yatay ölçeklenebilir düğümleri kullanıyor.

Ancak, farklı kırıklar üzerinde sorgu çalıştırmanız gerekirse, sıkıntılar olacaktır.


İlgilenen olursa, ben bir süre önce bir merhaba-dünya paylaşma uygulaması yaptım. Burada bir blog yazısında tartışılmıştır . RavenDB ve C # kullandım ama detaylar ilgisiz ve fikir aynı.


7

Veriler ne tür bir makinede saklanacak? Paylaşılan bir depolama aygıtı mı?

Sorgu süresini dikte edecek nihai faktör sabit sürücüleriniz olacak. Veritabanları ve sorgu iyileştiricileri, disk G / Ç sayısını mümkün olduğunca azaltmak için tasarlanmıştır. Sadece 3 tablonuz olduğu göz önüne alındığında, bu oldukça güvenilir bir şekilde yapılacaktır.

Bir sabit sürücünün okuma / yazma hızları, bellek hızlarından 200-300 kat daha yavaş olacaktır. Hızlı gecikme ve hızlı okuma ve yazma hızlarına sahip sabit disk sürücüleri arayın. Tüm bu veriler 2 TB'lik bir sürücüdeyse, sorguların bitmesi için muhtemelen uzun bir süre bekleyeceksiniz. Sabit gecikme süresi ~ 10-15 milisaniye, bellek gecikme süresi 10 nanosaniyeden az. Sabit sürücü gecikme süresi, bellek gecikme süresinden 1000-2000x daha yavaş olabilir. Mekanik kolun sabit sürücü üzerindeki hareketi, tüm sistemdeki en YÜKSEL şeydir.

Ne kadar RAM'in var? 16 GB? Diyelim ki 32 kayıt tutmanıza izin veriyor. 16000 dosyanız var. Tüm veri noktalarını doğrusal olarak tarayacaksanız, yalnızca arama süresinde 5-10 saniye ile kolayca sonlandırabilirsiniz. Sonra transfer hızı faktörü 50mb / s? Yaklaşık 7 saat. Ek olarak, geçici olarak kaydedilen herhangi bir verinin, okunan yeni verilere yer açmak için sabit sürücüde saklanması gerekecektir.

Diğer kullanıcılar tarafından aktif olarak kullanılan paylaşılan bir depolama cihazı kullanıyorsanız ... en iyi seçeneğiniz her şeyi gece çalıştırmaktır.

İç içe sorguların sayısını azaltmak da yardımcı olur. İç içe geçmiş sorgular, sabit sürücünüzü daha da artıracak geçici tablolara neden olur. Umarım sabit diskinizde boş alan vardır.

Sorgu optimizasyonu bir seferde yalnızca 1 sorguya bakabilir. Dolayısıyla iç içe geçmiş seçim ifadeleri optimize edilemez. Ancak, belirli bir iç içe geçmiş sorgunun döndürülecek küçük bir veri kümesiyle sonuçlanacağını biliyorsanız, saklayın. Sorgu optimizasyonu histogramları ve kaba varsayımları kullanır, eğer veriler ve sorgu hakkında bir şey biliyorsanız, devam edin ve yapın.

Verilerinizin diskte depolanma şekli hakkında ne kadar çok şey bilirseniz, sorularınızı o kadar hızlı yazabilirsiniz. Her şey birincil anahtarda sıralı olarak depolandıysa, yuvalanmış bir sorgudan döndürülen birincil anahtarları sıralamak yararlı olabilir. Ayrıca, önceden analiz etmeniz gereken veri kümelerini azaltabilirseniz, bunu yapın. Sisteminize bağlı olarak, dosya başına yaklaşık 1 saniye veri transferine bakarsınız.

Ad değerlerini (varchars) değiştirecekseniz, onu maksimum boyutta bir veri türüne değiştiririm, parçalanmayı önler ve işlem sadece bir kaç bayt bellek daha olur. Belki de maksimum 100 olan bir NVARCHAR.

Tablo denormalizing hakkında yorumlar kadar. Veri noktalarını daha büyük gruplarda (belki de spektrumlar gibi) depolamak ve sonra veri analizini python veya veritabanı ile etkileşime giren bir dilde saklamak en iyisi olabilir. Senin bir SQL sihirbazın olmadığı sürece.


3
Sabit sürücü ve bellek gecikmesindeki büyük farkı vurguluyorsunuz ancak sayılarınız 1000 faktörü ile kapalı. Sabit disklerin gecikme süresi yaklaşık 10 ms ve bellek 10ns ise, gecikmeler 1000 faktörü ile farklılık göstermiyorsa 1.000.000!
spectre256

6

Bana göre burada açıklandığı gibi "ilişkisel sütun deposu" gibi bir şey istediğiniz bir kullanım senaryosu gibi geliyor .

Tasarımı yanlış anlıyor olabilirim, ancak öncelikle büyük bir dizi koleksiyonla uğraşıyorsanız, bunları tipik satır yönelimli tablolarda saklamak, her bir öğenin bir dilime benzer olduğu anlamına gelir. Dilimlere tipik bir şekilde bakmakla ilgileniyorsanız, bu mantıklıdır, ancak bir seferde tüm sütunlara gerçekten bakıyorsanız daha az etkili olabilir.

Dizileri geri alırken, yalnızca normalleştirme işleminizden kaynaklanan başka bir tabloyla birleştirmenize gerek kalmaz, aynı zamanda diziyi karma değil de bir dizi olarak alabilirsiniz.

Sorunu gerçekten yanlış anlıyor olabilirim ve belirli bir çözüm önerem bile.

İşte gerçekten güncel veya konuşlandırılabilir bir çözüm olmasa bile, alakalı olabilecek başka bir konuşma .


6

Masanızı denemenizi ve bölümlendirmenizi tavsiye ederim. Tek bir masada 80 milyondan fazla satır var (borsa verileri) ve bu konuya hızlı bir şekilde erişmekte sorun yaşıyoruz.

Verilerinizi nasıl aramak istediğinize bağlı olarak, bölümlerinizi tasarlamanız gerekir. Bizim durumumuzda tarihe göre iyi çalışıyor çünkü belirli tarihleri ​​araştırıyoruz.

http://dev.mysql.com/doc/refman/5.1/en/partitioning-limitations.html

http://www.slideshare.net/datacharmer/mysql-partitions-tutorial


5

Evet ama...

2 milyar satırlık masalarla çalıştım. Ancak, yalnızca PK kullanan sorguların hızlı olması bekleniyordu.

En önemlisi, donanım tüm tabloları belleğe sığacak kadar RAM'e sahipti. Bu bir sorun haline geldiğinde (o sırada maksimum 96 GB'a kadar), her makineye yerleştirilen masa boyutunu hala belleğe sığacak kadar küçük tutarak dikey bölümlemeye gitti. Ayrıca, makineler 10 Gb fiber üzerinden bağlandı, bu nedenle ağ çıkışı bu kadar önemli değildi.

BTW. şemanız NoSQL çözümüne uyan, run_idspektrumlar spectrum_idiçin anahtar ve veri noktaları için anahtar olarak kullanan bir şeye benziyor .


4

Bu konuyu blogumda yazdım: http://www.tocker.ca/2013/10/24/improving-the-performance-of-large-tables-in-MySQL.html

Bazı kilit noktaları tekrarlamak için:

  • B-ağaçları büyüdükçe bozuluyor ve hafızaya sığmıyorlar (MySQL burada yalnız değil).
  • InnoDB, bazı performansın sürdürülmesine yardımcı olacak bazı özelliklere sahiptir (tamponlamayı değiştirin; daha önce 'insert buffer' adı verilir).
  • Bölümleme de yardımcı olabilir.

Yazım Tim Callaghan'ın yorumunda buna bağlı: http://www.tokutek.com/resources/benchmark-results/benchmarks-vs-innodb-hdds/#iiBench

IBench benchmark kullanarak 1 Milyar satır ekleme gösterir.

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.