MEMORY depolama motorunu MySQL'de kullanmanın nedenleri ** NOT **?


28

Geçenlerde MySQL'in farkında olmadığım bir "bellek" motoruna sahip olduğunu keşfettim (veritabanı çalışmamın çoğu hobi projeleri içindir, bu yüzden ne kadar ihtiyacım olursa olsun öğrenirim). Bu seçenek bana önemli ölçüde geliştirilmiş performans vermeli gibi görünüyor, bu yüzden onunla ilgili herhangi bir sakıncaları olup olmadığını merak ediyorum. Tanıdığım iki kişi:

  1. Söz konusu masaları tutabilmek için yeterli RAM'e ihtiyacım var.
  2. Makine kapanırsa masalar kaybolur.

AWS EC2 kullandığım için # 1'in sorun olmaması gerektiğine ve gerektiğinde daha fazla bellek içeren bir örnek türüne geçebileceğime inanıyorum. Gerektiği gibi diske geri bırakarak # 2'yi azaltabileceğime inanıyorum.

Başka neler var? Bellek motoru şimdiye kadar MyISAM veya InnoDB'den daha kötü performans verebilir mi? Sanırım endekslerin bu motorla farklı olduğu bir şey okudum; Endişelenmem gereken bir şey mi var?

Yanıtlar:


27

Http://dev.mysql.com/doc/refman/5.1/en/memory-storage-engine.html adresindeki özellik kullanılabilirliği listesine bakarak iki olası sorun ortaya çıkıyor:

  1. Hiçbir işlem veya FK desteği yoktur, yani işlem bütünlüğünü ve kendi kodunuzdaki referans bütünlüğünü yönetmeniz gerekeceği anlamına gelir (bu, DB'nin bunu sizin için yapmasına izin vermekten çok daha az verimli olmasına neden olabilir). beklenen davranış kalıpları).
  2. Yalnızca tablo düzeyinde kilitleme: Uygulamanızın aynı tablo kümesine birden fazla eşzamanlı yazıcıya gereksinim duyması veya okuma işlemlerinin tutarlı verilerin okunmasını sağlamak için kilit kullanması durumunda - bu gibi durumlarda disk tabanlı bir tablo çok daha ince kilidi destekler. İçeriği şu anda RAM'de önbelleğe alınmışsa, ayrıntı düzeyi çok daha iyi sonuç verir.

Bunun dışında, yeterli RAM’iniz olduğunu varsayarsak, bellek tabanlı bir tablonun disk tabanlı olandan daha hızlı olması gerekir. Açıkçası, sunucu örneği sıfırlanırken ne olacağı sorununu gidermek için anlık görüntüleri diske çekmeyi hesaba katmanız gerekir; bu, verilerin sık sık yakalanması gerekiyorsa (eğer bir gününü kaybederek yaşayabilirseniz) genel olarak performans avantajını tamamen reddetme olasılığı yüksektir. Böyle bir durumda, verileri günde yalnızca bir kez yedekleyebilirsiniz, ancak çoğu durumda kabul edilemez.

Bir alternatif olabilir:

  1. Disk tabanlı tabloları kullanın, ancak herhangi bir zamanda hepsini RAM'de tutmak için yeterli RAM'in olduğundan emin olun (ve "yeterli RAM", makinenizdeki diğer işlemleri hesaba katmanız gerektiği gibi düşündüğünüzden daha fazla olabilir. IO tamponları / önbellek vb.
  2. İçeriği belleğe önceden yüklemek ve SELECT * FROM <table> ORDER BY <pkey fields>ardından SELECT <indexed fields> FROM <table> ORDER BY <index fields>her dizin için her dizin için her başlangıçtaki tablonun tüm içeriğini (tüm veriler ve dizin sayfaları) tarayın

Bu şekilde tüm verileriniz RAM'dedir, yalnızca yazma işlemleri için G / Ç performansı konusunda endişelenmeniz gerekir. Uygulamanızın ortak çalışma kümesi tüm DB'den çok daha küçükse (genellikle durum budur - çoğu uygulamada çoğu kullanıcı yalnızca en son zamanlardaki verilere bakar), ne kadarının daha seçici olacağı konusunda daha iyi olabilirsiniz geri kalanı talep üzerine diskten yüklenmesine izin vererek belleğe önceden yüklemek için tarayın.


Neden bir bellek içi veritabanı için işlem bütünlüğüne ihtiyacınız var? Güç kesilirse, yine de her şeyinizi kaybediyorsunuz.
osa

@osa: Her şeyi serileştirmek yerine eşzamanlı erişime izin verdiğini varsayarsak, bunun için bir çeşit bütünlük yönetimi isteyeceksiniz.
David Spillett

14

Bellek depolama motorunu kullanmamanız gereken birçok durum vardır - ve InnoDB ne zaman daha hızlı olacaktır. Sadece eşzamanlılık hakkında düşünmeniz gerekir, önemsiz tek dişli testleri değil.

Yeterince büyük bir arabellek havuzunuz varsa, InnoDB de okuma işlemleri için tamamen bellekte yerleşik hale gelecektir. Veritabanlarının önbellekleri var . Kendilerini ısıtıyorlar!

Ayrıca - satır düzeyinde kilitleme ve MVCC değerini küçümsemeyin (okuyucular yazarları engellemez). Yazma diske devam etmesi gerektiğinde "yavaş" olabilir. Ancak en azından bir hafıza masasında olduğu gibi yazma işlemi sırasında engellemeyeceksiniz (MVCC yok; masa seviyesi kilitlemesi).


3

Kayıt için. Bazı bilgileri depolamak için Hafıza'daki Mysql tablolarını test ettim. Ve aynı bilgiyi saklamak için PHP'nin APC'sini (APCu) test ettim.

58000 kayıtlar için. (varchar + tamsayı + tarih).

  1. Orijinal bilgiler 24mb metin biçiminde (csv biçiminde).
  2. PHP'nin APC'si 44.7 MB RAM kullanıyor.
  3. Mysql's Table 575 MB RAM kullanıyor.

Tablo sadece tek bir indekse sahip, bu yüzden ana faktör olduğunu sanmıyorum.

Sonuç:

Bellek tablosu "büyük" tablolar için bir seçenek değildir, çünkü çok fazla bellek kullanır.


2
Bu basitleştirilmiş bir cevaptır. MEMORY depolama motoru, daha küçük veri tipleri kullanılarak, BTREE'yi endeks tipi olarak açıkça tanımlayarak ve RAM'e yüklenen veri miktarını sınırlayarak ayarlanabilir. Küçük setler için hala uygun bir seçenek. Agresif disk G / Ç gibi başka faktörler de vardır. Yayınlarımdaki Bkz dba.stackexchange.com/questions/6156/... ve dba.stackexchange.com/questions/2868/... )
RolandoMySQLDBA

Aslında, dizini değiştirmeyi kontrol ettim (ve hatta tamamen sildim) ve boyut çok fazla değişmedi (tablonun sıfırdan yeniden oluşturulması dahil). IMHO Mysql, kaputun altında bir şey yapıyor, bir tür optimizasyon veya sütun başına en büyük boyutu tahsis ediyor olabilir (örneğin bir varchar).
magallanes

6
Bunun nedeni neredeyse kesinlikle "MEMORY tables use a fixed-length row-storage format. Variable-length types such as VARCHAR are stored using a fixed length." VARCHAR'ınızdan kaynaklanıyor: dev.mysql.com/doc/refman/5.6/en/memory-storage-engine.html Etkili bir şekilde VARCHAR'ın MEMORY motoruyla CHAR olduğu anlaşılıyor.
Matthew1471,

2

MEMORY tabanlı tabloların diğer bir dezavantajı, aynı sorguda birden çok kez yönlendirilememeleridir. En azından bu davranış v5.4'e kadar bulundu. CTE'lerde (v8.x'ten beri) karmaşık işlemler için mem tabanlı ara tabloları kullanmaya gerek yoktur.


1

MySQL ve MariaDB kılavuzlarına göre, BLOB ve CLOB (çeşitli TEXT tipleri) MEMORY saklama tarafından desteklenmiyor. Kendi amaçlarımızla bu, MEMORY depolama motorunu neredeyse işe yaramaz hale getirdi.

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

BELLEK tabloları BLOB veya TEXT sütunlarını içeremez.

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

MEMORY tablolarında VARCHAR gibi değişken uzunluklu tipler kullanılabilir. BLOB veya TEXT sütunları MEMORY tabloları için desteklenmiyor.

Veritabanının sadece bir kısmını BELLEKİ depolamaya dönüştürmeye çalışırken, depolararası motorun yabancı anahtarlarının desteklenmediğini tespit ettim. Bu nedenle, BLOB / CLOB içeren tablolara yabancı anahtar referansları olması gereken tüm tablolar da bellek dışı saklama türlerinde olmalıdır (en azından bu InnoDB alt tablolarını etkiler).


1

HAFIZA tabloları, özellikle büyük veri alt kümeleri veya saklamanın kritik olduğu herhangi bir şey için kalıcı depolama için tasarlanmamıştır. Deneyimlerimden elde ettikleri en iyi amaç, karmaşık prosedürler sırasında geçici tabloların yaratılması ve popülasyonu sırasında geçici kayıtları tutmaktır; bu, motor için anahtar arabellek eşiğinizin gerçekleşmeyecek kadar yüksek olması koşuluyla, bu amaç için diğer tablo türlerinin çoğundan önemli ölçüde daha hızlı performans gösterir. bir disk yazma. Bu, disk G / Ç olmadığından ve belirli bir prosedür içinde kapsüllenmiş bir masa söz konusu olduğunda, indeksleme ve ilişkilerin, bu kadar önemli olmadıklarından dolayı, bu amaç için MyISAM veya InnoDB'den daha hızlı bir büyüklük sırası çalıştırabilir. ısrarın beklendiği yerde olur.


1

Önceki cevaplara ek olarak. doğrudan MySQL 5.7 kılavuzundan:

"MEMORY performansı, güncellemeleri işlerken tek iş parçacığı yürütme ve masa üstü ek yükünden kaynaklanan çekişme ile sınırlandırılmıştır. Bu, yük arttığında, özellikle de yazma içeren ifade karışımları için ölçeklenebilirliği sınırlar."

... ve bu çok gerçek bir sınırlama. Örneğin: güzel hızlı MEMORY temp tabloları oluşturmaya çalışan birden fazla oturumunuz olduğunda, tek iş parçacığı ciddi bir performans darboğazına neden olabilir.

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.