it-swarm.asia

Bisakah MySQL secara wajar melakukan kueri pada miliaran baris?

Saya berencana menyimpan pindaian dari spektrometer massa dalam database MySQL dan ingin tahu apakah menyimpan dan menganalisis jumlah data ini layak atau tidak. Saya tahu kinerja sangat bervariasi tergantung pada lingkungan, tetapi saya mencari urutan besarnya: apakah permintaan akan memakan waktu 5 hari atau 5 milidetik?

Masukkan format

Setiap file input berisi proses spektrometer tunggal; setiap proses terdiri dari satu set pemindaian, dan setiap pemindaian memiliki larik titik data yang dipesan. Ada sedikit metadata, tetapi sebagian besar file terdiri dari array 32 atau 64 bit atau mengapung.

Sistem host

 | ---------------- + --------------------------- ---- | 
 | OS | Windows 2008 64-bit | 
 | Versi MySQL | 5.5.24 (x86_64) | 
 | CPU | 2x Xeon E5420 (total 8 inti) | 
 | RAM | 8GB | 
 | Sistem file SSD | 500 GiB | 
 | HDD RAID | 12 TiB | 
 | ---------------- + ------------------------------- | 

Ada beberapa layanan lain yang berjalan di server menggunakan waktu prosesor yang dapat diabaikan.

Statistik file

 | ------------------ + -------------- | 
 | jumlah file | ~ 16.000 | 
 | ukuran total | 1.3 TiB | 
 | ukuran min | 0 byte | 
 | ukuran maksimal | 12 GiB | 
 | Berarti | 800 MiB | 
 | Median | 500 MiB | 
 | Total datapoints | ~ 200 miliar | 
 | ------------------ + -------------- | 

Jumlah total titik data adalah perkiraan kasar sangat .

Skema yang diajukan

Saya berencana melakukan hal-hal "benar" (yaitu menormalkan data seperti orang gila) dan akan memiliki tabel runs, tabel spectra dengan kunci asing ke runs , dan tabel datapoints dengan kunci asing ke spectra.

Dataran data 200 miliar pertanyaan

Saya akan menganalisis berbagai spektrum dan bahkan mungkin beberapa berjalan, menghasilkan pertanyaan yang dapat menyentuh jutaan baris. Dengan asumsi saya mengindeks semuanya dengan benar (yang merupakan topik untuk pertanyaan lain) dan saya tidak mencoba mengocok ratusan MiB di seluruh jaringan, apakah masuk akal jika MySQL menangani hal ini?

Informasi tambahan

Data pemindaian akan berasal dari file dalam format berbasis XML mzML . Daging format ini ada di <binaryDataArrayList> elemen tempat data disimpan. Setiap pemindaian menghasilkan> = 2 <binaryDataArray> elemen yang, jika digabungkan, membentuk larik 2 dimensi (atau lebih) dari bentuk [[123.456, 234.567, ...], ...].

Data-data ini ditulis sekali, jadi perbarui kinerja dan keamanan transaksi bukan masalah.

Rencana naif saya untuk skema database adalah:

runs tabel

 | nama kolom | ketik | 
 | ------------- + ------------- | 
 | id | KUNCI UTAMA | 
 | start_time | TIMESTAMP | 
 | nama | VARCHAR | 
 | ------------- + ------------- | 

spectra tabel

 | nama kolom | ketik | 
 | ---------------- + ------------- | 
 | id | KUNCI UTAMA | 
 | nama | VARCHAR | 
 | indeks | INT | 
 | spectrum_type | INT | 
 | representasi | INT | 
 | run_id | KUNCI LUAR NEGERI | 
 | ---------------- + ------------- | 

datapoints tabel

 | nama kolom | ketik | 
 | ------------- + ------------- | 
 | id | KUNCI UTAMA | 
 | spectrum_id | KUNCI LUAR NEGERI | 
 | mz | GANDA | 
 | num_counts | GANDA | 
 | indeks | INT | 
 | ------------- + ------------- | 

Apakah ini masuk akal?


Jadi, karena Anda mungkin dapat menyimpulkan, saya adalah programmer, bukan ahli biologi di lab, jadi saya tidak tahu sains hampir sama baiknya dengan ilmuwan yang sebenarnya.

Berikut adalah plot spektrum tunggal (pemindaian) dari jenis data yang akan saya hadapi:

Viewer screenshot

Tujuan dari perangkat lunak ini adalah untuk mencari tahu di mana dan seberapa signifikan puncaknya. Kami menggunakan paket perangkat lunak berpemilik untuk mencari tahu ini sekarang, tetapi kami ingin menulis program analisis kami sendiri (dalam R) sehingga kami tahu apa yang sedang terjadi di bawah lembaran. Seperti yang Anda lihat, sebagian besar data tidak menarik, tetapi kami tidak ingin membuang data yang berpotensi bermanfaat yang terlewatkan oleh algoritma kami. Setelah kami memiliki daftar kemungkinan puncak dengan mana kami puas, sisa jalur pipa akan menggunakan daftar puncak itu daripada daftar mentah titik data. Saya kira itu akan cukup untuk menyimpan datapoints mentah sebagai gumpalan besar, sehingga mereka dapat dianalisis kembali jika perlu, tetapi hanya menyimpan puncak sebagai entri database yang berbeda. Dalam hal ini, hanya akan ada beberapa lusin puncak per spektrum, sehingga hal-hal penskalaan gila seharusnya tidak menjadi masalah besar.

285
haxney

Saya tidak terlalu terbiasa dengan kebutuhan Anda, tetapi mungkin menyimpan setiap titik data dalam basis data sedikit berlebihan. Kedengarannya hampir seperti mengambil pendekatan menyimpan perpustakaan gambar dengan menyimpan setiap piksel sebagai catatan terpisah dalam database relasional.

Sebagai aturan umum, sebagian besar waktu menyimpan data biner dalam database adalah salah. Biasanya ada cara yang lebih baik untuk menyelesaikan masalah. Meskipun secara inheren tidak salah untuk menyimpan data biner dalam basis data relasional, seringkali kerugiannya lebih besar daripada keuntungannya. Database relasional, seperti namanya, paling cocok untuk menyimpan data relasional. Data biner tidak bersifat relasional. Ini menambah ukuran (sering secara signifikan) ke database, dapat merusak kinerja, dan dapat menimbulkan pertanyaan tentang mempertahankan miliaran catatan MySQL. Berita baiknya adalah ada basis data yang sangat cocok untuk menyimpan data biner. Salah satunya, meskipun tidak selalu jelas, adalah sistem file Anda! Cukup datang dengan direktori dan struktur penamaan file untuk file biner Anda, simpan yang ada di DB MySQL Anda bersama dengan data lain yang dapat menghasilkan nilai melalui kueri.

Pendekatan lain akan menggunakan sistem penyimpanan berbasis dokumen untuk data Anda titik (dan mungkin spektrum) data, dan menggunakan MySQL untuk berjalan (atau mungkin menempatkan berjalan ke dalam DB yang sama dengan yang lain).

117

Saya pernah bekerja dengan database MySQL yang sangat besar (Terabyte +). Meja terbesar yang kami miliki adalah lebih dari satu miliar baris. Ini menggunakan MySQL 5.0, jadi mungkin saja semuanya membaik.

Itu berhasil. MySQL memproses data dengan benar sebagian besar waktu. Itu sangat sulit sekalipun. (Jika Anda ingin ketersediaan enam level sigma dengan satu terabyte data, jangan gunakan MySQL. Kami adalah startup yang tidak memiliki DBA dan dana terbatas.)

Mencadangkan dan menyimpan data adalah tantangan. Diperlukan waktu berhari-hari untuk mengembalikan tabel jika perlu.

Kami memiliki banyak tabel dalam kisaran 10-100 juta baris. Setiap bergabung dengan signifikan ke meja terlalu memakan waktu dan akan memakan waktu selamanya. Jadi kami menulis prosedur tersimpan untuk 'berjalan' tabel dan proses bergabung dengan rentang 'id. Dengan cara ini, kami akan memproses data 10-100.000 baris sekaligus (Gabung dengan id 1-100.000 kemudian 100.001-200.000, dll.). Ini secara signifikan lebih cepat daripada bergabung dengan seluruh tabel.

Menggunakan indeks pada tabel yang sangat besar yang tidak didasarkan pada kunci utama juga jauh lebih sulit. Mysql 5.0 menyimpan indeks dalam dua bagian - ia menyimpan indeks (selain indeks primer) sebagai indeks ke nilai kunci utama. Jadi pencarian diindeks dilakukan dalam dua bagian: Pertama MySQL pergi ke indeks dan menarik darinya nilai kunci primer yang perlu ditemukan, kemudian melakukan pencarian kedua pada indeks kunci utama untuk menemukan di mana nilai-nilai tersebut.

Net dari ini adalah bahwa untuk tabel yang sangat besar (1-200 Juta plus baris) pengindeksan terhadap tabel lebih ketat. Anda membutuhkan lebih sedikit, indeks yang lebih sederhana. Dan melakukan bahkan pernyataan pilih sederhana yang tidak secara langsung pada indeks mungkin tidak akan pernah kembali. Di mana klausa harus menekan indeks atau melupakannya.

Tapi semua yang dikatakan, semuanya benar-benar berhasil. Kami dapat menggunakan MySQL dengan tabel yang sangat besar ini dan melakukan perhitungan serta mendapatkan jawaban yang benar.

Mencoba melakukan analisis pada 200 miliar baris data akan membutuhkan perangkat keras yang sangat canggih dan banyak pegangan tangan dan kesabaran. Hanya menyimpan data yang dicadangkan dalam format yang dapat Anda pulihkan akan menjadi pekerjaan yang signifikan.

Saya setuju dengan jawaban srini.venigalla itu menormalkan data seperti orang gila mungkin bukan ide yang baik di sini. Melakukan penggabungan beberapa tabel dengan banyak data akan membuka Anda dengan risiko jenis file yang bisa berarti beberapa pertanyaan Anda tidak akan pernah kembali. Denormallisasi dengan kunci integer yang sederhana akan memberi Anda peluang sukses yang lebih baik.

Semua yang kami miliki adalah InnoDB. Mengenai MyISAM vs InnoDB: Hal utama adalah untuk tidak mencampur keduanya. Anda tidak dapat benar-benar mengoptimalkan server untuk keduanya karena cara MySQL menyimpan kunci dan data lainnya. Pilih satu atau yang lain untuk semua tabel di server jika Anda bisa. MyISAM dapat membantu dengan beberapa masalah kecepatan, tetapi mungkin tidak membantu dengan pekerjaan DBA keseluruhan yang perlu dilakukan - yang bisa menjadi pembunuh.

111
Kevin Bedell

normalisasi data seperti orang gila

Normalisasi data seperti orang gila mungkin bukan strategi yang tepat dalam kasus ini. Biarkan opsi Anda tetap terbuka dengan menyimpan data baik dalam bentuk Normalisasi dan juga dalam bentuk tampilan terwujud yang sangat cocok untuk aplikasi Anda. Kunci jenis aplikasi ini BUKAN menulis permintaan adhoc. Pemodelan kueri lebih penting daripada pemodelan data. Mulailah dengan kueri target Anda dan bekerja menuju model data yang optimal.

Is this reasonable?

Saya juga akan membuat tabel datar tambahan dengan semua data.

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

Saya akan menggunakan tabel ini sebagai sumber utama dari semua kueri. Alasannya adalah untuk menghindari keharusan melakukan penggabungan. Bergabung tanpa pengindeksan akan membuat sistem Anda sangat tidak dapat digunakan, dan memiliki indeks pada file sebesar itu akan sama mengerikannya.

Strategi adalah, kueri terlebih dahulu pada tabel di atas, buang hasilnya ke temp table dan gabungkan temp table dengan mencari tabel Run and Spectrum dan dapatkan data yang Anda inginkan.


Sudahkah Anda menganalisis kebutuhan Tulis vs kebutuhan Baca? Akan sangat menggoda untuk membuang SQL dan pergi ke mekanisme penyimpanan data yang tidak standar. Menurut saya, itu harus menjadi pilihan terakhir.

Untuk mempercepat kecepatan tulis, Anda mungkin ingin mencoba metode Handler Socket. Percona, jika saya ingat, mengemas Socket Handler dalam paket instal mereka. (tidak ada hubungannya dengan Percona!)

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

70
srini.venigalla

Jawaban singkatnya adalah ya yang memenuhi syarat - karena jumlah baris menumbuhkan skema, tipe data, dan operasi yang Anda pilih semakin penting.

Seberapa banyak Anda menormalkan data Anda tergantung pada operasi yang Anda rencanakan untuk dilakukan pada data yang disimpan. Tabel 'datapoints' Anda khususnya tampaknya bermasalah - apakah Anda berencana membandingkan titik ke-n dari spektrum yang diberikan dengan tanggal yang lain? Jika tidak, menyimpannya secara terpisah bisa menjadi kesalahan. Jika titik data Anda tidak berdiri sendiri tetapi masuk akal hanya dalam konteks spektrum terkait mereka, Anda tidak memerlukan KUNCI UTAMA - kunci asing untuk spektrum dan kolom 'n' (kolom 'indeks' Anda) akan cukup. .

Tentukan operasi antar dan intra-spektrum yang harus Anda lakukan dan kemudian cari cara termurah untuk mencapainya. Jika hanya diperlukan persamaan, mereka mungkin didenormalisasi - mungkin dengan beberapa metadata statistik pra-kalkulasi yang membantu operasi Anda. Jika Anda benar-benar membutuhkan akses in-SQL ke titik data individual, pastikan Anda mengurangi ukuran setiap baris ke jumlah bidang minimum dan datatype terkecil yang mungkin.

MySQL terbesar yang pernah saya kelola secara pribadi adalah ~ 100 juta baris. Pada ukuran ini Anda ingin pertahankan baris Anda dan dengan demikian ukuran bidang Anda tetap - ini memungkinkan MySQL menghitung posisi setiap baris dalam tabel secara efisien dengan mengalikan kali ukuran tetap dari setiap baris (pikirkan pointer arithmetic) - meskipun detail yang tepat tergantung pada mesin penyimpanan yang Anda rencanakan untuk digunakan. Gunakan MyISAM jika Anda dapat melakukannya, kekurangan keandalannya dalam kecepatan, dan dalam situasi Anda seharusnya sudah cukup. Ganti bidang ukuran variabel seperti VARCHAR dengan CHAR (n) dan gunakan RTRIM () pada permintaan baca Anda.

Setelah baris tabel Anda memiliki lebar tetap, Anda dapat mengurangi jumlah byte dengan mengevaluasi MySQL integer datatypes (beberapa di antaranya non-standar). Setiap penghematan 1-byte yang dapat Anda tambahkan dengan mengubah INT 4-byte menjadi MEDIUMINT 3-byte menghemat Anda ~ 1MB per juta baris - artinya lebih sedikit disk I/O dan caching yang lebih efektif. Gunakan tipe data sekecil mungkin yang bisa Anda dapatkan . Hati-hati mengevaluasi jenis floating point dan lihat apakah Anda dapat mengganti DOUBLE 8-byte dengan FLOAT 4-byte atau bahkan <8 byte NUMERIC titik tetap . Jalankan tes untuk memastikan bahwa apa pun yang Anda pilih tidak menggigit Anda nanti.

Bergantung pada properti yang diharapkan dari dataset Anda dan operasi yang diperlukan mungkin ada penghematan lebih lanjut dalam pengkodean nilai-nilai Anda yang lebih tidak biasa (pola/pengulangan yang diharapkan yang dapat dikodekan sebagai indeks ke dalam serangkaian nilai, data mentah yang mungkin hanya berkontribusi secara bermakna ke metadata dan dibuang, dll) - meskipun optimisasi eksotis, tidak intuitif, destruktif hanya bermanfaat ketika setiap opsi lain telah dicoba.

Yang paling penting, apa pun yang Anda lakukan, jangan menganggap Anda telah memilih skema yang sempurna dan kemudian mulai membabi buta 10s dari jutaan rekaman. Desain yang baik membutuhkan waktu untuk berkembang. Buat kumpulan data uji yang besar namun dapat dikelola (katakanlah, 1-5%) dan verifikasi kebenaran dan kinerja skema Anda. Lihat kinerja berbagai operasi (http://dev.mysql.com/doc/refman/5.0/en/using-explain.html) dan pastikan Anda menyeimbangkan skema Anda untuk mendukung operasi yang paling sering.

Apakah saya mengatakan singkat? Aduh. Bagaimanapun, semoga berhasil!

33
Ryan Flynn

Tampaknya satu-satunya alasan untuk merobek data titik data dari XML (sebagai lawan dari metadata seperti waktu dan jenis lari) dan ke dalam bentuk database adalah ketika Anda menganalisis spektrum melintasi array - yaitu mungkin menemukan semua berjalan dengan tanda tangan tertentu. Hanya Anda yang tahu domain masalah Anda saat ini, tetapi ini bisa mirip dengan menyimpan sampel musik pada 96kHz dengan 1 sampel per baris. Saya tidak yakin ukuran adalah masalah lebih dari bagaimana data digunakan. Meminta seluruh data akan sama dengan menanyakan amplitudo relatif 2 menit ke dalam lagu di semua lagu oleh The Beatles. Jika Anda mengetahui jenis analisis yang mungkin dilakukan, sangat mungkin melakukan ini pada sinyal dan menyimpannya dalam metadata tentang proses mungkin lebih masuk akal.

Saya juga tidak yakin apakah data sumber Anda jarang. Sangat mungkin bahwa spektrum dalam database hanya boleh memasukkan entri yang tidak nol, sedangkan XML asli menyertakan entri nol, sehingga jumlah baris Anda bisa jauh lebih sedikit daripada dalam data sumber.

Jadi, seperti banyak pertanyaan, sebelum bertanya tentang MySQL yang menangani model Anda, melangkah mundur dan melihat modelnya dan bagaimana model itu akan digunakan mungkin lebih tepat daripada mengkhawatirkan kinerja dulu.


Setelah meninjau pembaruan pertanyaan Anda, saya pikir model di mana data biner disimpan sebagai BLOB atau hanya sebuah pointer ke file sudah cukup dan bekerja pada memodifikasi model Anda untuk menyimpan data tentang puncak signifikan yang telah diidentifikasi ketika data pertama kali Baca.

23
Cade Roux

Saya menjalankan layanan analisis web dengan sekitar 50 server basis data, masing-masing berisi banyak tabel lebih dari 100 juta baris, dan beberapa yang cenderung lebih dari satu miliar baris, kadang-kadang hingga dua miliar (pada setiap server).

Performa di sini baik-baik saja. Ini adalah data yang sangat normal. Namun - perhatian utama saya dengan membaca ini adalah bahwa Anda akan lebih baik dari 4,2 miliar tanda baris untuk tabel ini (mungkin bukan "berjalan" tetapi mungkin dua lainnya), yang berarti Anda harus menggunakan BIGINT daripada INT untuk kunci utama/asing.

Kinerja MySQL dengan bidang BIGINT dalam kolom yang diindeks adalah sangat mengerikan dibandingkan dengan INT. Saya membuat kesalahan dengan melakukan hal ini sekali dengan meja yang saya pikir akan tumbuh melebihi ukuran ini, dan begitu mencapai beberapa ratus juta baris, performanya sangat buruk. Saya tidak memiliki angka mentah tetapi ketika saya mengatakan buruk, maksud saya Windows ME buruk.

Kolom ini adalah kunci utama. Kami mengubahnya kembali menjadi hanya INT dan presto magico, kinerjanya baik lagi.

Semua server kami pada saat itu menggunakan Debian 5 dan dengan MySQL 5.0. Kami telah meningkatkan ke Debian 6 dan Percona MySQL 5.5, jadi hal-hal mungkin telah membaik sejak saat itu. Tetapi berdasarkan pengalaman saya di sini, tidak, saya tidak berpikir itu akan bekerja dengan baik.

18
Sean

Apakah itu berfungsi atau tidak, Anda akan selalu mengalami masalah yang sama dengan media penyimpanan monolitik tunggal: disk lambat. Pada 100 MB/s (cukup bagus untuk media pemintalan) dibutuhkan 3 jam hanya untuk membaca tabel 1TB; itu dengan asumsi tidak ada analisis atau pencarian atau penundaan lain memperlambat Anda.

Inilah sebabnya mengapa hampir setiap instalasi "data besar" menggunakan semacam penyimpanan data terdistribusi. Anda dapat menghabiskan 8 kali lebih banyak uang untuk membangun satu komputer super luar biasa untuk menjalankan DB, tetapi jika Anda memiliki banyak data yang dapat dipindai secara paralel, Anda hampir selalu lebih baik mendistribusikan beban di 8 komputer yang lebih murah.

Proyek seperti hadoop dibuat khusus untuk tujuan seperti ini. Anda membangun sekelompok komputer murah, mendistribusikan data di semua dari mereka, dan permintaan mereka secara paralel. Ini hanya salah satu dari setengah solusi yang dibangun berdasarkan ide yang sama, tetapi ini adalah solusi yang sangat populer.

18
tylerl

Hm ... Saya melihat dua alasan mengapa Anda memilih jenis struktur data ini:

  • anda benar-benar perlu melakukan datapoint vs kueri datapoint
  • anda bermaksud melakukan semua logika Anda dalam SQL

Sekarang, saya akan menyarankan untuk memeriksa persyaratan Anda dan memverifikasi bahwa setidaknya satu dari asumsi di atas benar. Jika tidak ada yang benar, Anda hanya membuat segalanya lebih lambat. Untuk jenis dataset ini, saya sarankan pertama-tama mencari tahu bagaimana data diharapkan untuk diakses, akurasi seperti apa yang Anda perlukan, dll - dan kemudian desain database Anda di sekitar itu.

P.S .: Ingatlah bahwa Anda membutuhkan setidaknya 36 + 5 byte per titik data, jadi dengan 200B titik data yang harus memberi Anda setidaknya 8,2 TB ruang yang dibutuhkan.

PPS: Anda tidak memerlukan kolom id di tabel datapoints, sebuah PRIMARY KEY (spectrum_id, index) mungkin cukup (hanya berhati-hatilah bahwa index mungkin merupakan kata yang dilindungi undang-undang) )

13

EDIT:

JANGAN MELAKUKANNYA DALAM MYSQL DENGAN DATA YANG DISIMPAN PADA TUNGGAL SATU. Hanya membaca bahwa jumlah data dari satu media akan memakan waktu berjam-jam. Anda perlu SKALA KELUAR, BUKAN ATAS.

Dan Anda perlu mendenormalisasi data Anda jika Anda ingin melakukan analisis data yang efektif. Anda tidak merancang sistem online di sini. Anda ingin angka-angka, desain yang sesuai.

Jawaban asli di bawah baris.


Jawabannya akan bervariasi tergantung pada permintaan Anda, MySQL mungkin bukan alat terbaik untuk pekerjaan ini. Anda mungkin ingin melihat solusi yang dapat Anda skala "keluar" dan tidak "naik". Jika Anda bersedia melakukan upaya mungkin Anda harus melihat pada solusi Mengurangi Peta seperti Hadoop.

Jika Anda ingin melakukan lebih banyak permintaan ad-hoc Google's BigQuery solusi mungkin cocok untuk Anda. Presentasi yang relevan dari Google I/O 2012: Memecah Data Besar dengan BigQuery

Jadi, solusinya akan tergantung pada apakah ini adalah hal satu-shot dan jika Anda ingin mendukung permintaan ad hoc secara wajar.

12
mdolk

Tidak ada yang menyebutkan, jadi saran saya. Lihatlah solusi MySQL yang banyak dihancurkan. Misalnya, lihat ini sangat dihargai tumblr presentation .

Konsepnya adalah:

  • Alih-alih satu database ekstra besar
  • Gunakan banyak yang kecil yang memegang bagian dari data asli

Dengan demikian Anda dapat mengukur secara horizontal, alih-alih mencoba meningkatkan kinerja vertikal. Google BigTable dan GFS juga menggunakan node yang dapat diskalakan secara horizontal untuk menyimpan dan meminta petabyte data.

Namun, akan ada masalah jika Anda perlu menjalankan kueri atas pecahan yang berbeda.


Jika ada yang tertarik, saya membuat aplikasi sharding hello-world beberapa waktu lalu. Itu dibahas di sini dalam posting blog. Saya menggunakan RavenDB dan C # tetapi detailnya tidak relevan dan idenya sama.
9
oleksii

Mesin seperti apa data akan disimpan? Apakah ini perangkat penyimpanan bersama?

Faktor utama yang akan menentukan waktu permintaan Anda akan menjadi perangkat keras Anda. Database dan pengoptimal kueri mereka dirancang untuk mengurangi jumlah disk I/Os sebanyak mungkin. Karena Anda hanya memiliki 3 tabel, ini akan dilakukan dengan cukup andal.

Kecepatan baca/tulis harddisk akan 200-300 kali lebih lambat daripada kecepatan memori. Carilah perangkat keras dengan latensi yang sangat cepat dan kecepatan baca dan tulis yang cepat. Jika semua data ini menggunakan satu drive 2-TB, Anda mungkin akan menunggu waktu yang lama untuk menyelesaikan pertanyaan. Harddrive latency adalah ~ 10-15milliseconds sedangkan latency memori kurang dari 10nanoseconds. Harddrive latency bisa 1000-2000x lebih lambat dari latensi memori. Pergerakan lengan mekanis pada harddisk adalah yang TERLambat dalam keseluruhan sistem ini.

Berapa banyak RAM yang Anda miliki? 16gb? Katakanlah yang memungkinkan Anda menyimpan 32 catatan. Anda memiliki 16000 file. Jika Anda akan memindai linear semua titik data, Anda dapat dengan mudah berakhir dengan 5-10 detik untuk mencari waktu sendirian, lalu faktor dalam kecepatan transfer 50mb/dtk? Sekitar 7 jam. Selain itu, setiap data yang disimpan sementara harus disimpan pada harddirve untuk memberikan ruang bagi data baru yang sedang dibaca.

Jika Anda menggunakan perangkat penyimpanan bersama yang digunakan secara aktif oleh pengguna lain ... taruhan terbaik Anda akan menjalankan semuanya pada malam hari.

Mengurangi jumlah kueri bersarang juga membantu. Kueri bersarang menghasilkan tabel sementara yang akan menghancurkan hard drive Anda lebih banyak lagi. Saya harap Anda memiliki banyak ruang kosong di harddisk Anda.

Optimasi kueri hanya dapat melihat 1 kueri sekaligus. Jadi pilih pernyataan bersarang tidak dapat dioptimalkan. NAMUN, jika Anda tahu permintaan bersarang tertentu akan menghasilkan set data kecil untuk dikembalikan, simpanlah. Optimasi kueri menggunakan histogram dan asumsi kasar, jika Anda mengetahui sesuatu tentang data dan kueri, silakan dan lakukan.

Semakin banyak Anda tahu tentang cara data Anda disimpan di disk, semakin cepat Anda dapat menulis pertanyaan Anda. Jika semuanya disimpan secara berurutan pada kunci utama, mungkin bermanfaat untuk mengurutkan kunci primer yang dikembalikan dari kueri bersarang. Juga, jika Anda dapat mengurangi set kumpulan data yang perlu Anda analisis sama sekali sebelumnya, lakukanlah. Tergantung pada sistem Anda, Anda melihat sekitar 1 detik transfer data per file.

Jika Anda akan memodifikasi nilai Name (varchars) saya akan mengubahnya ke tipe data dengan ukuran maksimum, itu akan mencegah fragmentasi dan trade off hanya beberapa byte memori. Mungkin NVARCHAR dengan maksimum 100.

Sejauh komentar tentang denormalisasi tabel. Saya pikir mungkin yang terbaik untuk hanya menyimpan datapoints dalam kelompok yang lebih besar (mungkin sebagai spektra) dan kemudian melakukan analisis data dalam python atau bahasa yang berinteraksi dengan database. Kecuali jika Anda menggunakan SQL- Penyihir.

7
JustinDanielson

Bagi saya itu terdengar seperti skenario penggunaan di mana Anda menginginkan sesuatu seperti "toko kolom relasional" seperti dijelaskan di sini .

Saya mungkin salah memahami desain, tetapi jika Anda terutama berurusan dengan koleksi array yang besar, menyimpannya dalam tabel berorientasi baris yang khas berarti bahwa setiap elemen mirip dengan slice. Jika Anda tertarik untuk melihat irisan dengan cara yang tipikal, itu masuk akal, tetapi bisa jadi kurang efisien jika Anda benar-benar melihat seluruh kolom sekaligus.

Saat mengambil array, tidak hanya Anda mungkin tidak perlu bergabung dengan tabel lain yang dihasilkan dari normalisasi Anda, tetapi Anda dapat mengambil seri sebagai array daripada hash.

Saya mungkin benar-benar salah paham masalah, dan saya bahkan tidak menyarankan solusi spesifik.

Ini pembicaraan lain yang mungkin relevan, bahkan jika itu bukan solusi saat ini atau yang bisa digunakan.

6
RandallZ

Saya sarankan Anda mencoba dan mempartisi meja Anda. Kami memiliki lebih dari 80 juta baris dalam satu tabel (data pasar saham) dan tidak mengalami kesulitan mengaksesnya dengan cepat.

Bergantung pada bagaimana Anda bermaksud mencari data Anda, Anda harus mendesain partisi Anda. Dalam kasus kami menurut tanggal berfungsi dengan baik karena kami meminta tanggal tertentu.

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

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

6
user9866

Ya, tapi ...

Saya telah bekerja dengan tabel yang memiliki 2 milyar baris. Namun hanya pertanyaan yang menggunakan PK diharapkan cepat.

Yang paling penting, perangkat keras memiliki cukup RAM agar sesuai dengan seluruh tabel dalam memori. Ketika itu menjadi masalah (maks. Pada 96GB pada waktu itu), pergi untuk partisi vertikal, menjaga ukuran meja diatur pada setiap mesin cukup kecil untuk tetap muat di memori. Juga, mesin terhubung melalui serat 10Gb, sehingga throughput jaringan tidak banyak masalah.

BTW. skema Anda terlihat seperti sesuatu, yang bisa masuk ke dalam solusi NoSQL, menggunakan run_id sebagai kunci hashing untuk spektra dan spectrum_id sebagai kunci hashing untuk titik data.

5
vartec

Saya telah menulis tentang topik ini di blog saya: http://www.tocker.ca/2013/10/24/improving-the-performance-of-large-tables-in-MySQL.html =

Untuk mengulangi beberapa poin utama:

  • B-tree menurunkan karena semakin besar dan tidak muat ke dalam memori (MySQL tidak sendirian di sini).
  • InnoDB memang memiliki beberapa fitur untuk membantu mempertahankan kinerja (ubah buffering; sebelumnya disebut 'sisipkan buffer').
  • Partisi juga dapat membantu.

Dalam komentar di pos saya, Tim Callaghan menautkan ini: http://www.tokutek.com/resources/benchmark-results/benchmarks-vs-innodb-hdds/#iiBench

Yang menunjukkan memasukkan 1 Miliar baris menggunakan tolok ukur iibench.

4
Morgan Tocker