it-swarm.asia

ما هي أسباب عدم استخدام محرك التخزين MEMORY في MySQL **؟

اكتشفت مؤخرًا أن MySQL يحتوي على محرك "ذاكرة" لم أكن على دراية به (معظم أعمال قاعدة البيانات الخاصة بي مخصصة لمشروعات الهوايات لذا أتعلم ما أحتاجه أثناء التنقل). يبدو أن هذا الخيار يجب أن يعطيني أداءً محسنًا بشكل كبير ، لذلك أتساءل عما إذا كانت هناك أي عيوب تتوافق معه. الاثنان اللذان أعرفهما هما:

  1. أحتاج إلى ما يكفي RAM لإبقاء الجدول (الجداول) المعنية).
  2. يتم فقدان الجداول إذا تم إيقاف تشغيل الجهاز.

أعتقد أن رقم 1 لا ينبغي أن يكون مشكلة لأنني أستخدم AWS EC2 ويمكنني الانتقال إلى نوع مثيل به ذاكرة أكبر إذا لزم الأمر. أعتقد أنه يمكنني تخفيف رقم 2 عن طريق الإغراق مرة أخرى إلى القرص حسب الحاجة.

ما هي القضايا الأخرى الموجودة؟ هل يمكن لمحرك الذاكرة أن يعطي أداءً أسوأ من MyISAM أو InnoDB؟ أعتقد أنني قرأت شيئًا يختلف عن المؤشرات في هذا المحرك ؛ هل هذا شيء يجب أن أقلق بشأنه؟

30
Michael McGowan

بالنظر إلى قائمة توفر الميزات على http://dev.mysql.com/doc/refman/5.1/en/memory-storage-engine.html مشكلتان محتملتان تقفزان:

  1. لا يوجد دعم للمعاملات أو FK ، مما يعني أنه سيتعين عليك إدارة تكامل المعاملات والتكامل المرجعي في التعليمات البرمجية الخاصة بك (والتي قد تكون في النهاية أقل كفاءة بكثير من السماح لقاعدة البيانات بالقيام بذلك نيابة عنك ، على الرغم من أن ذلك يعتمد كثيرًا على تطبيقك أنماط السلوك المتوقعة).
  2. القفل على مستوى الجدول فقط: يمكن أن يكون هذا حاجزًا كبيرًا أمام قابلية التوسع إذا كان تطبيقك يحتاج إلى العديد من الكتّاب المتزامنين لنفس المجموعة من الجداول أو في الحالات التي تستخدم فيها عمليات القراءة أقفال لضمان قراءة البيانات المتسقة - في مثل هذه الحالات ، يكون الجدول المستند إلى القرص الذي يدعم دقة قفل أكثر دقة وأداء أفضل بكثير إذا تم تخزين ما يكفي من محتواه في ذاكرة التخزين المؤقت حاليًا.

بخلاف ذلك ، بافتراض أن لديك ذاكرة وصول عشوائي كافية ، يجب أن يكون الجدول المستند إلى الذاكرة أسرع من القرص المستند إلى القرص. من الواضح أنك بحاجة إلى أخذ اللقطات إلى القرص لمعالجة مشكلة ما يحدث عند إعادة تعيين مثيل الخادم ، والذي من المحتمل أن ينفي تمامًا فائدة الأداء بشكل عام إذا كانت البيانات تحتاج إلى الالتقاط كثيرًا (إذا كنت تستطيع العيش مع فقدان يوم من البيانات في مثل هذه الحالة ، يمكنك فقط أخذ نسخة احتياطية مرة واحدة يوميًا ، ولكن في معظم الحالات لن يكون ذلك مقبولًا).

قد يكون البديل عن:

  1. استخدم الجداول المستندة إلى القرص ، ولكن تأكد من أن لديك ما يكفي من RAM للاحتفاظ بها جميعًا في RAM في أي وقت معين (و "RAM كافية" قد تكون أكثر مما تعتقد أنك بحاجة إلى حساب أي عمليات أخرى على الجهاز ، OS IO المخازن المؤقتة/ذاكرة التخزين المؤقت وما إلى ذلك)
  2. امسح محتويات الجدول بالكامل (جميع البيانات وصفحات الفهرس) في كل بدء تشغيل لتحميل المحتوى مسبقًا في الذاكرة باستخدام SELECT * FROM <table> ORDER BY <pkey fields> لكل جدول يليه SELECT <indexed fields> FROM <table> ORDER BY <index fields> لكل فهرس

بهذه الطريقة تكون جميع بياناتك في ذاكرة الوصول العشوائي (RAM) ، ما عليك سوى القلق بشأن أداء الإدخال/الإخراج لعمليات الكتابة. إذا كانت مجموعة العمل الشائعة لتطبيقك أصغر بكثير من قاعدة البيانات بأكملها (وهو ما يحدث عادة - في معظم التطبيقات ، لن ينظر معظم المستخدمين إلى أحدث البيانات إلا إذا كان الوقت) ، فقد تكون أفضل أن تكون أكثر انتقائية بشأن مقدار تقوم بالمسح الضوئي للتحميل المسبق في الذاكرة ، مما يسمح بتحميل الباقي من القرص عند الطلب.

27
David Spillett

هناك الكثير من الحالات لعدم استخدام محرك تخزين الذاكرة - وعندما يكون InnoDB أسرع. تحتاج فقط إلى التفكير في التزامن وليس مجرد اختبارات خيوط متواضعة.

إذا كان لديك تجمع مؤقت كبير بما فيه الكفاية ، فإن InnoDB سيصبح مقيمًا بالكامل في الذاكرة لعمليات القراءة أيضًا. قواعد البيانات لها مخابئ . يسخنون أنفسهم!

أيضًا - لا تستهين بقيمة القفل على مستوى الصف و MVCC (لا يحظر القراء الكتاب). قد يكون "أبطأ" عندما يجب أن تستمر الكتابة إلى القرص. ولكن على الأقل لن يتم حظره أثناء عملية الكتابة هذه كما لو كنت على طاولة ذاكرة (لا يوجد MVCC ؛ تأمين مستوى الجدول).

15
Morgan Tocker

للتسجيل. لقد اختبرت جداول Mysql في الذاكرة لتخزين بعض المعلومات. وقمت باختبار APC (APCu) الخاص بـ PHP لتخزين نفس المعلومات.

لـ 58000 سجل. (varchar + integer + date).

  1. معلومات أصلية 24 ميجا بايت بتنسيق نص (تنسيق csv).
  2. يستخدم APC الخاص بـ PHP 44.7 ميجابايت من ذاكرة الوصول العشوائي.
  3. يستخدم جدول Mysql 575 ميجابايت من ذاكرة الوصول العشوائي.

يحتوي الجدول على فهرس واحد فقط لذلك لا أعتقد أنه العامل الرئيسي.

استنتاج:

جدول الذاكرة ليس خيارًا للجداول "الكبيرة" لأنه يستخدم مساحة كبيرة من الذاكرة.

3
magallanes

العيب الآخر للجداول المستندة إلى MEMORY هو أنه لا يمكن إحالتها عدة مرات في نفس الاستعلام. على الأقل تم العثور على هذا السلوك حتى v5.4. كيف مع CTEs (منذ v8.x) ليست هناك حاجة لاستخدام الجداول المتوسطة المستندة إلى mem للإجراءات المعقدة.

2
Kondybas

بالإضافة إلى الإجابات السابقة. مباشرة من دليل MySQL 5.7:

"أداء الذاكرة مقيَّد بسبب التنافس الناتج عن تنفيذ مؤشر ترابط واحد وأعلى تأمين الجدول عند معالجة التحديثات. وهذا يحد من قابلية التوسع عند زيادة التحميل ، خاصة لمزيج البيانات التي تتضمن عمليات الكتابة."

... وهذا قيد حقيقي للغاية. على سبيل المثال: عندما يكون لديك جلسات متعددة تحاول إنشاء جداول مؤقتة لسرعة ذاكرة جيدة ، يمكن أن يتسبب الترابط الفردي في اختناق أداء خطير.

1
Eljuan

لا تُعد جداول MEMORY للتخزين المستمر ، خاصةً بالنسبة لمجموعات فرعية كبيرة من البيانات أو أي شيء يكون فيه الاحتفاظ أمرًا بالغ الأهمية. أفضل غرض من تجربتي هو الاحتفاظ بسجلات عابرة أثناء إنشاء الجداول المؤقتة وعددها أثناء الإجراءات المعقدة ، والتي تعمل بشكل أسرع بكثير من معظم أنواع الجداول الأخرى لهذا الغرض بشرط تعيين حد المخزن المؤقت الرئيسي للمحرك مرتفعًا بما يكفي لعدم تكبده كتابة قرص. يمكن أن يعمل هذا الأمر بحجم أسرع من MyISAM أو InnoDB لهذا الغرض حيث لا يوجد قرص I/O ، وفي حالة وجود جدول مغلف ضمن إجراء معين ، فإن الفهرسة والعلاقات لا تحمل أهمية مثلما سوف حيث يتوقع المثابرة.

1
mopsyd

وفقًا لكتيبات MySQL و MariaDB ، لا تدعم وحدات التخزين MEMORY وحدات تخزين BLOB و CLOB (أنواع TEXT المختلفة). لأغراضنا الخاصة ، جعل هذا محرك التخزين MEMORY عديم الفائدة تقريبًا.

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

لا يمكن أن تحتوي جداول MEMORY على أعمدة BLOB أو TEXT.

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

يمكن استخدام أنواع متغيرة الطول مثل VARCHAR في جداول MEMORY. أعمدة BLOB أو TEXT غير معتمدة لجداول MEMORY.

عند محاولة تحويل جزء فقط من قاعدة البيانات إلى ذاكرة MEMORY ، اكتشفت أن المفاتيح الخارجية لمحرك التخزين الداخلي غير مدعومة. لذا ، فإن جميع الجداول ، التي يجب أن تحتوي على مراجع رئيسية أجنبية للجداول ، تحتوي على BLOB/CLOB يجب أن تكون أيضًا في أنواع تخزين غير ذاكرة (على الأقل ، هذا يؤثر على جداول InnoDB الفرعية).

1
user2134886