it-swarm.asia

Apa alasan ** BUKAN ** untuk menggunakan mesin penyimpanan MEMORY di MySQL?

Baru-baru ini saya menemukan bahwa MySQL memiliki mesin "memori" yang tidak saya sadari (sebagian besar pekerjaan basis data saya adalah untuk proyek-proyek hobi jadi saya belajar apa yang saya butuhkan saat saya pergi). Sepertinya opsi ini harus memberi saya peningkatan kinerja yang drastis, jadi saya bertanya-tanya apakah ada kekurangan yang menyertainya. Dua yang saya tahu adalah:

  1. Saya perlu memiliki cukup RAM untuk menahan tabel yang dipertanyakan).
  2. Tabel hilang jika mesin dimatikan.

Saya percaya # 1 seharusnya tidak menjadi masalah karena saya menggunakan AWS EC2 dan dapat pindah ke tipe instance dengan lebih banyak memori jika diperlukan. Saya percaya saya dapat mengurangi # 2 dengan membuang kembali ke disk sesuai kebutuhan.

Apa masalah lain yang ada? Dapatkah mesin memori memberikan kinerja yang lebih buruk daripada MyISAM atau InnoDB? Saya rasa saya membaca sesuatu yang indeksnya berbeda dengan mesin ini; Apakah ini sesuatu yang perlu saya khawatirkan?

30
Michael McGowan

Melihat daftar ketersediaan fitur di http://dev.mysql.com/doc/refman/5.1/en/memory-storage-engine.html dua kemungkinan masalah muncul:

  1. Tidak ada transaksi atau dukungan FK, yang berarti Anda harus mengelola integritas transaksional dan integritas referensial dalam kode Anda sendiri yang diperlukan (yang bisa menjadi jauh lebih efisien daripada membiarkan DB melakukan ini untuk Anda, meskipun itu sangat tergantung pada aplikasi Anda. pola perilaku yang diharapkan).
  2. Hanya penguncian tingkat tabel: ini bisa menjadi penghalang yang signifikan untuk skalabilitas jika aplikasi Anda membutuhkan beberapa penulis bersamaan ke set tabel yang sama atau dalam kasus di mana operasi membaca Anda menggunakan kunci untuk memastikan data yang konsisten dibaca - dalam kasus seperti itu sebuah tabel berbasis disk yang mendukung granularity kunci jauh lebih baik akan melakukan jauh lebih baik jika kontennya cukup saat ini di-cache dalam RAM.

Selain itu, dengan asumsi Anda memiliki RAM yang cukup, tabel berbasis memori harus lebih cepat daripada yang berbasis disk. Jelas Anda perlu mempertimbangkan untuk mengambil snapshot ke disk untuk mengatasi masalah apa yang terjadi ketika instance server diatur ulang, yang kemungkinan besar akan sepenuhnya meniadakan manfaat kinerja secara keseluruhan jika data perlu sering ditangkap (jika Anda dapat hidup dengan kehilangan satu hari dari data dalam keadaan seperti itu Anda hanya bisa mengambil cadangan sekali sehari, tetapi dalam kebanyakan kasus itu tidak dapat diterima).

Alternatif lain adalah:

  1. Gunakan tabel berbasis disk, tetapi pastikan Anda memiliki lebih dari cukup RAM untuk menyimpan semuanya dalam RAM pada waktu tertentu (dan "cukup RAM" mungkin lebih dari yang Anda pikirkan karena Anda perlu memperhitungkan proses lain pada mesin, OS IO buffer/cache dan sebagainya)
  2. Pindai seluruh konten (semua data dan halaman indeks) dari tabel pada setiap startup untuk memuat konten ke dalam memori dengan SELECT * FROM <table> ORDER BY <pkey fields> untuk setiap tabel diikuti oleh SELECT <indexed fields> FROM <table> ORDER BY <index fields> untuk setiap indeks

Dengan cara ini semua data Anda dalam RAM, Anda hanya perlu khawatir tentang kinerja I/O untuk operasi penulisan. Jika rangkaian kerja aplikasi Anda jauh lebih kecil daripada seluruh DB (yang biasanya terjadi - di sebagian besar aplikasi sebagian besar pengguna hanya akan melihat data terbaru paling banyak jika waktu itu), Anda mungkin lebih baik menjadi lebih selektif tentang berapa banyak Anda memindai untuk memuat ke dalam memori, memungkinkan sisanya untuk dimuat dari disk sesuai permintaan.

27
David Spillett

Ada banyak kasus untuk tidak menggunakan mesin penyimpanan memori - dan ketika InnoDB akan lebih cepat. Anda hanya perlu memikirkan konkurensi dan bukan tes ulir tunggal yang sepele.

Jika Anda memiliki kumpulan buffer yang cukup besar, maka InnoDB akan menjadi memori sepenuhnya untuk operasi baca juga. Database memiliki cache . Mereka menghangatkan diri!

Juga - jangan meremehkan nilai penguncian level baris dan MVCC (pembaca tidak memblokir penulis). Mungkin "lebih lambat" ketika menulis harus bertahan ke disk. Tapi setidaknya Anda tidak akan memblokir selama operasi penulisan seperti Anda berada di meja memori (tidak ada MVCC; penguncian level tabel).

15
Morgan Tocker

Untuk catatan. Saya menguji tabel Mysql di Memori untuk menyimpan beberapa informasi. Dan saya menguji PHP APC (APCu) untuk menyimpan informasi yang sama.

Untuk 58000 pendaftar. (varchar + integer + date).

  1. Informasi asli 24mb dalam format teks (format csv).
  2. APC PHP menggunakan 44,7mb RAM.
  3. Tabel Mysql menggunakan 575mb RAM.

Tabel hanya memiliki satu indeks jadi saya tidak berpikir itu adalah faktor utama.

Kesimpulan:

Tabel memori adalah bukan opsi untuk tabel "besar" karena menggunakan terlalu banyak memori.

3
magallanes

Kerugian lain dari tabel berbasis MEMORY adalah bahwa mereka tidak dapat dirujuk beberapa kali dalam permintaan yang sama. Setidaknya perilaku itu ditemukan sampai v5.4. Bagaimana dengan CTE (sejak v8.x) tidak perlu menggunakan tabel perantara berbasis mem untuk prosedur kompleks.

2
Kondybas

Selain jawaban sebelumnya. langsung dari manual MySQL 5.7:

"Kinerja MEMORY dibatasi oleh pertikaian yang dihasilkan dari eksekusi single-thread dan overhead kunci tabel saat memproses pembaruan. Ini membatasi skalabilitas ketika beban meningkat, terutama untuk campuran pernyataan yang mencakup penulisan."

... dan ini adalah batasan yang sangat nyata. Sebagai contoh: ketika Anda memiliki beberapa sesi mencoba membuat tabel temp MEMORY cepat bagus threading tunggal dapat menyebabkan hambatan kinerja yang serius.

1
Eljuan

Tabel MEMORY tidak dimaksudkan untuk penyimpanan persisten, khususnya subset besar data atau apa pun di mana penyimpanan sangat penting. Tujuan terbaik mereka dari pengalaman saya adalah untuk menyimpan catatan sementara selama pembuatan dan populasi tabel sementara selama prosedur kompleks, yang berkinerja lebih cepat secara signifikan daripada kebanyakan tipe tabel lainnya untuk tujuan ini asalkan ambang batas buffer utama Anda untuk mesin diatur cukup tinggi untuk tidak menimbulkan tulis disk. Ini dapat mengoperasikan urutan besarnya lebih cepat dari MyISAM atau InnoDB untuk tujuan ini karena tidak ada disk I/O, dan dalam kasus tabel yang dienkapsulasi dalam prosedur tertentu, pengindeksan dan hubungan tidak memiliki signifikansi sebanyak mereka akan di mana kegigihan diharapkan.

1
mopsyd

Menurut manual MySQL dan MariaDB, BLOB dan CLOB (berbagai jenis TEXT) tidak didukung oleh penyimpanan MEMORY. Untuk keperluan kita sendiri, ini membuat mesin penyimpanan MEMORY hampir tidak berguna.

http://dev.mysql.com/doc/refman/5.7/en/memory-storage-engine.html

Tabel MEMORY tidak boleh berisi kolom BLOB atau TEXT.

https://mariadb.com/kb/en/mariadb/memory-storage-engine/

Tipe panjang variabel seperti VARCHAR dapat digunakan dalam tabel MEMORY. Kolom BLOB atau TEXT tidak didukung untuk tabel MEMORY.

Ketika mencoba mengubah hanya sebagian dari database menjadi penyimpanan MEMORY, saya menemukan bahwa kunci asing mesin antar-penyimpanan tidak didukung. Jadi, semua tabel, yang harus memiliki referensi kunci asing ke tabel, berisi BLOB/CLOB juga harus dalam jenis penyimpanan non-memori (setidaknya, ini mempengaruhi tabel anak InnoDB).

1
user2134886