MySQL ประสิทธิภาพสูงสำหรับการเลือกจำนวนมาก / INSERTs / UPDATEs / DELETEs


9

ฉันกำลังสร้างโมดูลที่ผู้ใช้ทุกคนมักจะได้รับการบันทึกลงในตารางเป็นเวลา 10 ถึง 300 วินาที

เมื่อเวลาหมดอายุบันทึกจะถูกลบ กรณีคือ: จะมีผู้ใช้จำนวนมากและเรคคอร์ดจะเปลี่ยนแปลงบ่อยมาก - สิ่งนี้จะส่งผลต่อประสิทธิภาพของแอปพลิเคชั่นสำหรับตารางนี้อย่างไรเพราะเรคคอร์ดจะเปลี่ยนบ่อยมากและฉันสงสัยว่า mysql ดีกับมันหรือไม่? เช่นเดียวกับดัชนีที่จะมาและไปข้อมูลจะเปลี่ยนไปเช่น 200 ครั้ง / วินาทีสำหรับตารางนี้ บางทีฉันอาจเลือกวิธีที่ไม่ดีสำหรับงานประเภทนี้ ข้อเสนอแนะใด ๆ

ขอบคุณ!


2
คุณลองจัดเก็บข้อมูลใน memcache แล้วล้างข้อมูลในหนึ่งธุรกรรมทุกสองสามวินาทีหรือไม่

3
"ข้อมูลมีการเปลี่ยนแปลงอย่าง 200 ครั้ง / วินาทีสำหรับตารางนี้" ฉันคิดว่าเส้นที่สะกดออกมาข้อมูลนี้ควรจะถูกเก็บไว้ในหน่วยความจำอายุการใช้งานที่มันต้องคงอยู่มีน้อยมากดังนั้นอาจไม่ควรไปที่ดิสก์

ดัชนีมาแล้วไปไหน ฉันไม่สามารถคิดด้วยเหตุผลใด ๆ ว่าทำไมคุณต้องสร้างและวางดัชนีบ่อยมาก
Barry Brown

คำตอบ:


3

สิ่งหนึ่งที่จะต้องมีการพิจารณาเป็นวิธี MySQL ใช้บัฟเฟอร์สำหรับเครื่องมือการจัดเก็บข้อมูลที่สำคัญ: InnoDBและMyISAM

สิ่งที่อยู่ในหน่วยความจำแคชจะแตกต่างกันอย่างมากระหว่างเอนจินการจัดเก็บ

InnoDB เก็บแคชทั้งหน้าข้อมูลและหน้าดัชนี พวกเขาจะโหลดลงใน InnoDB บัฟเฟอร์สระว่ายน้ำซึ่งมีขนาดโดยinnodb_buffer_pool_size

MyISAM แคชหน้าเพียงดัชนีและพวกเขาจะโหลดลงในแคชคีย์ (Key บัฟเฟอร์) ซึ่งมีขนาดโดยkey_buffer_size

คุณต้องใช้information_schema.tablesเพื่อให้ได้ข้อมูลและดัชนีขนาดครอบครองบนดิสก์เพื่อขนาด InnoDB บัฟเฟอร์สระว่ายน้ำและ MyISAM แคชที่สำคัญได้อย่างถูกต้อง

ขึ้นอยู่กับจำนวนข้อมูลที่คุณมีและเวลาที่อนุญาตคุณสามารถอุ่นแคชดังนี้

สำหรับทุกโต๊ะTableT

  • ไปที่แต่ละดัชนีNDX
  • สำหรับแต่ละดัชนีNDX
    • เรียกใช้ SELECT ทุกคอลัมน์ใน NDX อย่างน้อยหนึ่งคอลัมน์ที่ไม่ได้จัดทำดัชนีในTableTจาก TableT

ด้วยการทำเช่นนี้คุณจะรับประกันได้ว่าทุกหน้าข้อมูลและดัชนีจะได้รับการอ่านอย่างน้อยหนึ่งครั้ง พวกเขาจะนั่งในแคช แนวคิดนี้มีประสบการณ์ในส่วนหนึ่งและในหลักการโดยPercona Percona สร้างแนวคิดนี้เข้าMK-ทาส prefetch โปรแกรมนี้ทำคืออะไร

  • อ่านล็อกรีเลย์บนสลาฟก่อนประมวลผลสคริปท์ SQL
  • ใช้คำสั่ง SQL จากบันทึกการถ่ายทอดและแปลงเป็น SELECT โดยใช้ส่วนคำสั่ง WHERE, GROUP BY และ ORDER BY เป็นแนวทางในการเลือกดัชนี
  • ดำเนินการคำสั่ง SELECT ที่มาจาก SQL ที่แปลงแล้ว

สิ่งนี้บังคับให้ทาสมี 99.99% ของข้อมูลที่ทาสต้องการเพื่อประมวลผล SQL อย่างรวดเร็ว สิ่งนี้ยังทำให้ทาสที่เตรียมไว้ในกรณีที่คุณล้มเหลวเป็นทาสด้วยตนเองและโปรโมตมันให้กับอาจารย์ที่มีเพียงแค่แคชชวลที่เหมือนกันกับคุณในฐานะอาจารย์ที่คุณล้มเหลวไป

สรุปผลการศึกษา

ไม่มีอะไรจะเต้นพร้อมแคชเต็มใจและสามารถให้คุณใช้ในสภาพแวดล้อมของการแทรกการปรับปรุงและการลบที่หนักหน่วง

ให้มันลอง !!!

ข้อแม้

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


5

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

"ผู้ใช้จำนวนมาก" ไม่ได้ช่วยใครเลยจริงๆ MySQL น่าจะดีถ้า "มาก" หมายถึงไม่กี่ร้อย (แม้ว่าจะขึ้นอยู่กับว่ามีฐานข้อมูลของคุณจัดการอยู่อีกหลายพันคนก็น่าจะทำงานเช่นกัน

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

แต่หากไม่มีตัวเลขจริงและข้อมูลบางอย่างเกี่ยวกับฮาร์ดแวร์ที่เซิร์ฟเวอร์ฐานข้อมูลของคุณใช้นั่นก็ไม่สามารถตอบได้อย่างแม่นยำ

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

ไม่แน่ใจ แต่มีตัวเลือกสำหรับ MySQL ที่อนุญาตให้แคชตารางในหน่วยความจำได้อย่างสมบูรณ์มันทำเช่นนี้ในหลาย ๆ สถานการณ์และส่วนใหญ่คุณจะไม่ต้องเปลี่ยนอะไรมาก แต่ถ้าคุณพูดถึงผู้ใช้และบันทึกจำนวนมากจริง ๆ คุณอาจปรับแต่งพารามิเตอร์บางอย่างเพื่อปรับการแคชให้เหมาะกับความต้องการพิเศษของคุณ


4
+1 สำหรับการแนะนำโซลูชันที่เก็บข้อมูลไว้ในหน่วยความจำ

3

นี่คือความคิดที่บ้า มันเกี่ยวข้องกับสมมุติฐานและแนวทางปฏิบัติที่ไม่แนะนำเสมอ (เช่นการอัปเดตคีย์) - ฉันจะได้รับการปฏิเสธจำนวนมากสำหรับการแนะนำสิ่งนี้ แต่ที่นี่จะไป ...

สมมติว่าคุณมีแถวจำนวนมากและมีปริมาณการลบสูงคุณสามารถปรับปรุงประสิทธิภาพการลบได้ด้วยการสร้างพาร์ติชั่น 2 พาร์ติชันบนโต๊ะของคุณ พาร์ติชันจะแตกต่างกันตามหลักแรกของคีย์ ตัวอย่าง:

ค่าคีย์ 1123234441 ใช้สำหรับแถวที่ใช้งานอยู่และค่าคีย์: 9123234441 ใช้สำหรับแถวที่ไม่ได้ใช้งาน (ตัวเลขแรกในตัวอย่างนี้ใช้ดังนี้: 1 = แอ็คทีฟ, 9 = ไม่แอ็คทีฟ)

ตอนนี้เมื่อผู้ใช้ลบแถวคุณไม่ได้ลบแถวคุณอัปเดตคีย์ (Ouch!) สิ่งนี้จะย้ายแถวไปยังพาร์ทิชันแถวที่ไม่ใช้งานโดยอัตโนมัติ

แน่นอนคุณต้อง จำกัด การเลือกของคุณในการอ่านข้อมูลจากพาร์ทิชันที่ใช้งานอยู่เท่านั้น ตอนนี้ส่วนที่เจ๋งคือการทิ้งพาร์ติชั่นแถวที่ไม่แอ็คทีฟนั้นรวดเร็วมาก

อย่างที่ฉันพูดไปก่อนหน้านี้ใช้งานได้ถ้าคุณมีเพียง 1 โต๊ะ ฉันยังไม่ได้ทดสอบสิ่งนี้ดังนั้นมันจึงเป็นเพียงวิธีการทางทฤษฎี แต่ฉันได้พบกับความเร็วของการแบ่งพาร์ติชันและมันก็รวดเร็วอย่างน่าอัศจรรย์

เพื่อปรับปรุงการเลือกของคุณให้ใช้การจัดทำดัชนีที่เหมาะสมและเพิ่มประสิทธิภาพการแทรกลดขนาดแถวและจำนวนของดัชนี (คำสั่งนี้เป็นเรื่องทั่วไปมาก ... )

สำหรับการอ้างอิงดู: http://dev.mysql.com/doc/refman/5.1/en/partitioning-types.html หวังว่านี่จะช่วยได้


2
ฉันไม่แน่ใจว่าถ้ามันเหมาะสมสำหรับปัญหาเฉพาะนี้ (ฉันยังเดาว่า mysql จะเก็บข้อมูลทั้งหมดและมีแนวโน้มว่าระเบียนเหล่านั้นจะไม่เห็นดิสก์เลย) แต่ +1 สำหรับการชี้ให้เห็นถึงเทคนิคการเพิ่มประสิทธิภาพที่น่าสนใจที่ฉันไม่ทราบในตอนนี้
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.