อะไรคือเหตุผล ** ไม่ ** ในการใช้เครื่องมือจัดเก็บข้อมูล MEMORY ใน MySQL?


28

ฉันเพิ่งค้นพบว่า MySQL มีเอ็นจิ้น "หน่วยความจำ" ที่ฉันไม่ทราบ ดูเหมือนว่าตัวเลือกนี้ควรให้ประสิทธิภาพที่ดีขึ้นอย่างมากกับฉันดังนั้นฉันจึงสงสัยว่ามีข้อบกพร่องใด ๆ ทั้งสองที่ฉันรู้คือ:

  1. ฉันต้องมี RAM เพียงพอที่จะถือตารางในคำถาม
  2. ตารางจะหายไปหากเครื่องปิด

ฉันเชื่อว่า # 1 ไม่ควรเป็นปัญหาเนื่องจากฉันใช้ AWS EC2 และสามารถย้ายไปยังประเภทอินสแตนซ์ที่มีหน่วยความจำเพิ่มขึ้นหากจำเป็น ฉันเชื่อว่าฉันสามารถลด # 2 ได้โดยการถ่ายโอนข้อมูลกลับไปที่ดิสก์ตามต้องการ

มีปัญหาอื่นอีกไหม เอ็นจิ้นหน่วยความจำสามารถให้ประสิทธิภาพที่แย่กว่า MyISAM หรือ InnoDB ได้หรือไม่? ฉันคิดว่าฉันอ่านบางอย่างที่ดัชนีแตกต่างจากเครื่องมือนี้ เป็นสิ่งที่ฉันต้องกังวลหรือไม่

คำตอบ:


27

ดูรายการความพร้อมใช้งานของคุณลักษณะที่http://dev.mysql.com/doc/refman/5.1/en/memory-storage-engine.htmlสองปัญหาที่เป็นไปได้:

  1. ไม่มีการทำธุรกรรมหรือการสนับสนุน FK หมายความว่าคุณจะต้องจัดการความสมบูรณ์ของธุรกรรมและความสมบูรณ์ในการอ้างอิงในรหัสของคุณเอง (ซึ่งอาจทำให้การทำงานมีประสิทธิภาพน้อยกว่าการให้ DB ทำสิ่งนี้ให้คุณแม้ว่าจะขึ้นอยู่กับแอปของคุณ รูปแบบพฤติกรรมที่คาดหวัง)
  2. การล็อกระดับตารางเท่านั้น: นี่อาจเป็นอุปสรรคสำคัญในการปรับขนาดได้หากแอปของคุณต้องการตัวเขียนพร้อมกันหลายตัวในชุดของตารางเดียวกันหรือในกรณีที่การดำเนินการอ่านของคุณใช้การล็อกเพื่อให้แน่ใจว่ามีการอ่านข้อมูลที่สอดคล้องกัน รองรับการล็อคที่ละเอียดกว่ามากจะทำงานได้ดีขึ้นถ้าเนื้อหาในแคชเพียงพอในปัจจุบันใน RAM

นอกเหนือจากนั้นสมมติว่าคุณมี RAM เพียงพอตารางตามหน่วยความจำควรเร็วกว่าดิสก์ที่ใช้ เห็นได้ชัดว่าคุณจำเป็นต้องคำนึงถึงปัจจัยในการถ่ายภาพสแนปชอตไปยังดิสก์เพื่อแก้ไขปัญหาที่เกิดขึ้นเมื่ออินสแตนซ์ของเซิร์ฟเวอร์ถูกรีเซ็ตซึ่งมีแนวโน้มที่จะลบล้างผลประโยชน์ด้านประสิทธิภาพโดยรวมหากข้อมูลต้องการถ่ายบ่อย ข้อมูลในอินสแตนซ์ดังกล่าวคุณสามารถสำรองข้อมูลได้หนึ่งครั้งต่อวัน แต่ในกรณีส่วนใหญ่ที่ไม่สามารถยอมรับได้)

ทางเลือกอื่นอาจเป็น:

  1. ใช้ตารางที่ใช้ดิสก์ แต่ให้แน่ใจว่าคุณมี RAM เพียงพอที่จะเก็บพวกเขาทั้งหมดใน RAM ในเวลาที่กำหนด (และ "RAM เพียงพอ" อาจมากกว่าที่คุณคิดเพราะคุณต้องคำนึงถึงกระบวนการอื่น ๆ บนเครื่อง OS IO บัฟเฟอร์ / แคชเป็นต้น)
  2. สแกนเนื้อหาทั้งหมด (หน้าข้อมูลและหน้าดัชนีทั้งหมด) ของตารางในแต่ละการเริ่มต้นเพื่อโหลดเนื้อหาลงในหน่วยความจำด้วยSELECT * FROM <table> ORDER BY <pkey fields>สำหรับแต่ละตารางตามด้วยSELECT <indexed fields> FROM <table> ORDER BY <index fields>สำหรับแต่ละดัชนี

วิธีนี้ข้อมูลทั้งหมดของคุณอยู่ใน RAM คุณเพียงแค่ต้องกังวลเกี่ยวกับประสิทธิภาพ I / O สำหรับการดำเนินการเขียน หากชุดการทำงานทั่วไปของแอปของคุณมีขนาดเล็กกว่าฐานข้อมูลทั้งหมด (ซึ่งมักเป็นกรณีนี้) ในแอปพลิเคชันส่วนใหญ่ผู้ใช้ส่วนใหญ่จะดูเฉพาะข้อมูลล่าสุดมากที่สุดในเวลานั้น) คุณอาจเลือกที่จะดีกว่า คุณสแกนเพื่อโหลดล่วงหน้าลงในหน่วยความจำทำให้สามารถโหลดส่วนที่เหลือจากดิสก์ตามต้องการ


ทำไมคุณต้องการความสมบูรณ์ของธุรกรรมสำหรับฐานข้อมูลในหน่วยความจำ หากไฟดับคุณก็สูญเสียทุกสิ่งไป
osa

@osa: สมมติว่ามันอนุญาตให้เข้าถึงพร้อมกันมากกว่าทุกสิ่งที่เป็นอันดับคุณจะต้องการรูปแบบของการจัดการความสมบูรณ์แบบ
David Spillett

14

มีหลายกรณีที่ไม่ต้องใช้เอนจินการเก็บข้อมูล - และเมื่อ InnoDB จะเร็วขึ้น คุณเพียงแค่ต้องคิดถึงการทำงานพร้อมกันและไม่ใช่การทดสอบเธรดเดี่ยว ๆ

หากคุณมีพูลบัฟเฟอร์ที่มีขนาดใหญ่พอ InnoDB จะกลายเป็นหน่วยความจำภายในสำหรับการอ่านเช่นกัน ฐานข้อมูลมีแคช พวกเขาอบอุ่นขึ้น!

นอกจากนี้ - อย่าประเมินค่าการล็อกระดับแถวต่ำเกินไปและMVCC (ผู้อ่านไม่บล็อกผู้เขียน) อาจเป็น "ช้าลง" เมื่อการเขียนต้องอยู่ในดิสก์ แต่อย่างน้อยคุณจะไม่ถูกบล็อกระหว่างการเขียนเช่นเดียวกับที่คุณอยู่ในตารางหน่วยความจำ (ไม่มี MVCC การล็อคระดับตาราง)


3

สำหรับบันทึก. ฉันทดสอบตาราง Mysql ใน Memory เพื่อเก็บข้อมูล และฉันทดสอบ PHP ของ APC (APCu) สำหรับเก็บข้อมูลเดียวกัน

สำหรับการลงทะเบียน 58000 (varchar + จำนวนเต็ม + วันที่)

  1. ข้อมูลดั้งเดิม 24mb ในรูปแบบข้อความ (รูปแบบ csv)
  2. APC ของ PHP ใช้ RAM ขนาด 44.7mb
  3. ตารางของ Mysql ใช้ RAM 575mb

ตารางมีดัชนีเดียวเท่านั้นดังนั้นฉันไม่คิดว่ามันเป็นปัจจัยหลัก

สรุป:

ตารางหน่วยความจำไม่ใช่ตัวเลือกสำหรับตาราง "ใหญ่"เนื่องจากใช้หน่วยความจำมากเกินไป


2
นี่เป็นคำตอบที่ธรรมดามาก เอ็นจิ้นการจัดเก็บ MEMORY สามารถปรับได้โดยใช้ชนิดข้อมูลที่เล็กลงกำหนด BTREE อย่างชัดเจนเป็นประเภทดัชนีและ จำกัด ปริมาณข้อมูลที่โหลดลงใน RAM มันยังคงเป็นตัวเลือกที่ทำงานได้สำหรับชุดเล็ก นอกจากนี้ยังมีปัจจัยอื่น ๆ เช่นดิสก์ I / O เชิงรุก ดูโพสต์ของฉันdba.stackexchange.com/questions/6156/ …และdba.stackexchange.com/questions/2868/ … )
RolandoMySQLDBA

ในความเป็นจริงฉันตรวจสอบการเปลี่ยนดัชนี (และลบอย่างสมบูรณ์) และขนาดก็ไม่เปลี่ยนแปลงมากนัก (รวมถึงการสร้างตารางใหม่ตั้งแต่เริ่มต้น) IMHO Mysql กำลังทำอะไรบางอย่างภายใต้ประทุนอาจเป็นการเพิ่มประสิทธิภาพหรือการจัดสรรขนาดที่ใหญ่ที่สุดต่อคอลัมน์ (เช่นใน varchar)
magallanes

6
เหตุผลเกือบแน่นอนเนื่องจาก VARCHAR ของคุณ: "MEMORY tables use a fixed-length row-storage format. Variable-length types such as VARCHAR are stored using a fixed length." dev.mysql.com/doc/refman/5.6/th/memory-storage-engine.htmlอย่างมีประสิทธิภาพก็จะปรากฏ VARCHAR กลายเป็น CHAR ด้วยเครื่องมือหน่วยความจำ
Matthew1471

2

ข้อเสียอื่น ๆ ของตารางที่ใช้หน่วยความจำคือพวกเขาไม่สามารถเรียกหลายครั้งในแบบสอบถามเดียวกัน อย่างน้อยก็พบพฤติกรรมดังกล่าวจนถึง v5.4 วิธีที่มี CTE (ตั้งแต่ v8.x) ไม่จำเป็นต้องใช้ตารางระดับกลางแบบอิง mem สำหรับโพรซีเดอร์ที่ซับซ้อน


1

ตามคู่มือ MySQL และ MariaDB BLOB และ CLOB (TEXT หลายประเภท) ไม่ได้รับการสนับสนุนจากหน่วยความจำ MEMORY เพื่อวัตถุประสงค์ของเราเองสิ่งนี้ทำให้เอ็นจิ้นการจัดเก็บข้อมูลของ 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

ตาราง MEMORY ไม่ได้มีไว้สำหรับที่จัดเก็บข้อมูลถาวรโดยเฉพาะอย่างยิ่งชุดย่อยของข้อมูลขนาดใหญ่หรือสิ่งใดก็ตามที่การเก็บรักษามีความสำคัญ จุดประสงค์ที่ดีที่สุดจากประสบการณ์ของฉันคือบันทึกบ้านชั่วคราวในระหว่างการสร้างและจำนวนประชากรของตารางชั่วคราวในระหว่างขั้นตอนที่ซับซ้อนซึ่งทำงานได้เร็วกว่าประเภทตารางส่วนใหญ่อื่น ๆ อย่างมีนัยสำคัญสำหรับวัตถุประสงค์นี้หากคุณตั้งค่าเกณฑ์บัฟเฟอร์หลักสำหรับเครื่องยนต์ ดิสก์เขียน สิ่งนี้สามารถดำเนินการตามลำดับความสำคัญได้เร็วกว่า MyISAM หรือ InnoDB สำหรับจุดประสงค์นี้เนื่องจากไม่มี I / O ของดิสก์และในกรณีของตารางที่ถูกห่อหุ้มอยู่ในกระบวนการเฉพาะการทำดัชนีและความสัมพันธ์นั้นไม่สำคัญเท่าที่ควร คาดว่าจะมีความเพียรอยู่


1

นอกจากคำตอบก่อนหน้า ตรงจากคู่มือ MySQL 5.7:

"ประสิทธิภาพของ MEMORY ถูก จำกัด โดยการช่วงชิงที่เกิดจากการดำเนินการแบบเธรดเดียวและค่าใช้จ่ายการล็อกตารางเมื่อประมวลผลการอัปเดตซึ่งจะ จำกัด ขีดความสามารถในการขยายเมื่อโหลดเพิ่มขึ้นโดยเฉพาะอย่างยิ่งสำหรับคำสั่งผสม

... และนี่คือข้อ จำกัด ที่แท้จริงมาก ตัวอย่างเช่น: เมื่อคุณมีหลายเซสชันที่พยายามสร้างตาราง MEMORY temp ที่รวดเร็วการทำเธรดเดี่ยวอาจทำให้เกิดปัญหาคอขวดอย่างร้ายแรง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.