จะปรับปรุง MySQL INSERT และ UPDATE ได้อย่างไร?


14

คำถามนี้อาจถูกถามใน StackOverflow ด้วยเช่นกัน แต่ฉันจะลองที่นี่ก่อน ...

ประสิทธิภาพของคำสั่ง INSERT และ UPDATE ในฐานข้อมูลของเราดูเหมือนจะลดระดับลงและทำให้ประสิทธิภาพในการทำงานของเว็บแอพของเราต่ำลง

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

ฉันคิดว่าเราอาจเห็นปัญหาการล็อคฉันจะทราบได้อย่างไร


ดีกว่าที่ dba.stackexchange.com
Pacerier

คำตอบ:


25
  1. ตรวจสอบว่าฮาร์ดแวร์และระบบปฏิบัติการของคุณได้รับการกำหนดค่าและปรับแต่งอย่างเหมาะสมหรือไม่:

    • แหล่งที่มาของปัญหา (การใช้ CPU / IO / หน่วยความจำ / การแลกเปลี่ยน) คุณมี IOP จำนวนมากหรือไม่ โหลดซีพียูหรือไม่ หากคุณมีการอ่าน IOP จำนวนมากอาจเป็นเพราะคุณมี InnoDB buffer_pool ไม่ใหญ่พอ หาก CPU โหลดอาจเป็นไปได้ว่าคิวรีของคุณทำการสแกนแบบเต็มตารางแทนที่จะใช้ดัชนีที่เหมาะสม
    • การตั้งค่าดิสก์ / RAID / LVM ในการตั้งค่าบางอย่างการทำแถบ LVMอาจให้ประโยชน์กับคุณโดย eqalizing โหลดดิสก์ (ไม่มี RAID ฮาร์ดแวร์เชื่อมต่อ LUNS หลายรายการ)
    • ตัวจัดกำหนดการ IO: เมื่อคุณมีตัวควบคุม RAID ของฮาร์ดแวร์ที่ดีอาจเป็น noop ที่ดีที่สุด RedHat ทำการทดสอบและพวกเขากล่าวว่าสำหรับ Oracle (และฐานข้อมูลอื่น ๆ ) CFQ เป็นตัวเลือกที่ดีที่สุด คุณต้องใช้การวัดประสิทธิภาพบางอย่าง (เช่น tpc-c หรือ tpc-e) และเลือกสิ่งที่ดีที่สุดสำหรับฮาร์ดแวร์ของคุณ
    • ระบบไฟล์ที่ดี - ext3 ทำงานได้ไม่ดีในปริมาณงานเฉพาะฐานข้อมูล ดีกว่าคือ XFS หรือ OCFS2 คุณต้องมีการวัดประสิทธิภาพอีกครั้ง
    • ดูว่าระบบของคุณใช้การสลับหรือไม่ การใช้ประสิทธิภาพ degrades แลกเปลี่ยน MySQL
  2. ตรวจสอบว่าอินสแตนซ์ MySQL / InnoDB ของคุณถูกปรับอย่างถูกต้องหรือไม่:

    • ขนาดพูลบัฟเฟอร์ - หน้าข้อมูลแคชในหน่วยความจำ
    • innodb_flush_method = O_DIRECT - หลีกเลี่ยงการบัฟเฟอร์คู่ IO
    • เพิ่มขนาดไฟล์บันทึก InnoDB - สำหรับปริมาณงานเขียนที่มากซึ่งสามารถปรับปรุงประสิทธิภาพได้ แต่อย่าลืม: ขนาดไฟล์บันทึกที่ใหญ่ขึ้นหมายถึงการกู้คืนระบบล้มเหลวอีก บางครั้งในชั่วโมง !!!
    • innodb_flush_log_at_trx_commit = 0 หรือ 2 - หากคุณไม่กังวลเกี่ยวกับ ACID และสามารถปล่อยธุรกรรมในวินาทีหรือสองครั้งสุดท้าย
    • key_buffer_size - สำคัญมากสำหรับ MyISAM แต่ใช้สำหรับตารางชั่วคราวดิสก์
    • ดูสถานะ INNODBของคุณ
  3. วิเคราะห์ภาระงานของคุณ - ตรวจสอบข้อความค้นหาทั้งหมดของคุณเพื่อบันทึกการทำงานช้าลงและเรียกใช้ mk-query-digest คุณสามารถสืบค้นคำสั่งทั้งหมดโดยใช้tcpdump และ maatkit
    • แบบสอบถามใดที่ใช้เวลาส่วนใหญ่ของเซิร์ฟเวอร์ของคุณ
    • มีการสร้างตารางชั่วคราวโดยเฉพาะตารางชั่วคราวที่มีขนาดใหญ่หรือไม่
    • เรียนรู้วิธีใช้อธิบาย
    • แอปพลิเคชันของคุณใช้ธุรกรรมหรือไม่ เมื่อคุณเรียกใช้คิวรีที่มี autocommit = 1 (ค่าเริ่มต้นกับ MySQL) แบบสอบถามการแทรก / อัปเดตทุกรายการจะเริ่มทรานแซกชันใหม่ซึ่งจะมีค่าใช้จ่าย ถ้าเป็นไปได้ควรปิดการใช้งาน autocommit (ใน python MySQL autocommit ถูกปิดการใช้งานตามค่าเริ่มต้น) และดำเนินการกระทำด้วยตนเองหลังจากทำการแก้ไขทั้งหมดแล้ว
    • แอปพลิเคชันของคุณสร้างชุดของส่วนแทรกลงในตารางเดียวกันในลูปหรือไม่ Load data infileคำสั่งนั้นเร็วกว่าสำหรับชุดของส่วนแทรก
    • โปรดจำไว้ว่า: select count(*) from table;innodb นั้นช้ากว่า myisam มาก
    • แบบสอบถาม INSERT / UPDATE ประเภทใดที่ใช้เวลาส่วนใหญ่ของเซิร์ฟเวอร์ พวกเขาจะเพิ่มประสิทธิภาพได้อย่างไร
    • ตรวจสอบว่า DB ของคุณมีดัชนีที่เหมาะสมหรือไม่และเพิ่มถ้าจำเป็น

ในสภาพแวดล้อมของเราเรามีสถานการณ์ว่าหนึ่งในแบบสอบถามแบบปรับปรุงนั้นช้า เวลาโดยประมาณในการเสร็จงานแบ็ตช์คือ 2 วัน !!! หลังจากการวิเคราะห์บันทึกการค้นหาช้าเราพบว่าแบบสอบถามการปรับปรุงประเภทนี้ต้องใช้เวลา 4 วินาทีจึงจะเสร็จสมบูรณ์ update table1 set field1=value1 where table1.field2=xx table2.field3=yy and table2.field4=zzแบบสอบถามมองเช่นนี้ หลังจากแปลงแบบสอบถามแบบใช้ปรับปรุงข้อมูลเพื่อเลือกแบบสอบถามและเรียกใช้อธิบายแบบสอบถามแบบใช้เลือกข้อมูลที่เราพบว่าแบบสอบถามประเภทนี้ไม่ได้ใช้ดัชนี หลังจากสร้างดัชนีที่เหมาะสมเราได้ลดเวลาในการดำเนินการคิวรี่การอัปเดตเป็นมิลลิวินาทีและงานทั้งหมดเสร็จในเวลาน้อยกว่าสองชั่วโมง

ลิงค์ที่มีประโยชน์:


ก่อนที่ทุกดัชนีที่ตรวจสอบ การย่อยสลายกลิ่นเช่น "เป็นตารางใหญ่ขึ้นเพราะเราไม่ได้ดัชนี"
TomTom

5

ด้วยการกำหนดค่าเริ่มต้นของ InnoDB คุณจะถูก จำกัด ความเร็วที่คุณสามารถเขียนและล้างข้อมูลธุรกรรมลงดิสก์ หากคุณสามารถจัดการกับการสูญเสีย ACID เล็กน้อยให้ทดลองใช้ innodb_flush_log_at_trx_commit ตั้งค่าเป็น 0 เพื่อเขียนและล้างบันทึกลงดิสก์ทุกวินาที ตั้งค่าเป็น 1 (ค่าเริ่มต้น) เพื่อเขียนและล้างข้อมูลในทุกการกระทำ ตั้งค่าเป็น 2 เพื่อเขียนไปยังไฟล์บันทึกหลังจากทุกการกระทำ แต่ล้างข้อมูลเพียงครั้งเดียวต่อวินาที

หากคุณสามารถรับมือกับการสูญเสียธุรกรรม 1s นี่อาจเป็นวิธีที่ดีในการปรับปรุงประสิทธิภาพการเขียนอย่างมากมาย

ยังใส่ใจกับสิ่งที่ดิสก์ของคุณกำลังทำ RAID 10> RAID 5 สำหรับการเขียนที่ราคาดิสก์เพิ่มเติม


1

ปัญหาการล็อคจะถูกตรวจสอบโดยสถานะการเชื่อมต่อใน show full processlist;

อ่านผ่านmy.cnfและเอกสาร MySQL ตัวเลือกการกำหนดค่าเป็นเอกสารที่ดีมาก

โดยทั่วไปคุณต้องการให้มีการประมวลผลในหน่วยความจำมากที่สุด สำหรับการปรับให้เหมาะสมของแบบสอบถามหมายถึงการหลีกเลี่ยงตารางชั่วคราว การประยุกต์ใช้ดัชนีที่เหมาะสม

การปรับแต่งจะเฉพาะเจาะจงกับเอ็นจิ้นฐานข้อมูลที่คุณต้องการและสถาปัตยกรรมแอปพลิเคชัน มีทรัพยากรมากมายที่มีอยู่ก่อนการค้นหาทางอินเทอร์เน็ต



0

InnoDB เป็นเครื่องมือที่ดีมาก อย่างไรก็ตามมันขึ้นอยู่กับการถูก 'ปรับ' สิ่งหนึ่งคือถ้าส่วนแทรกของคุณไม่อยู่ในลำดับการเพิ่มคีย์หลัก innoDB อาจใช้เวลานานกว่า MyISAM เล็กน้อย สิ่งนี้สามารถเอาชนะได้โดยการตั้งค่า innodb_buffer_pool_size ที่สูงขึ้น คำแนะนำของฉันคือตั้งไว้ที่ 60-70% ของ RAM ทั้งหมดของคุณ ฉันกำลังใช้งานเซิร์ฟเวอร์ดังกล่าว 4 ตัวในขณะนี้กำลังทำการผลิตประมาณ 3.5 ล้านแถวต่อนาที พวกเขามีเกือบ 3 เทราไบต์แล้ว InnoDB มันจะต้องเป็นเพราะแทรกพร้อมกันสูง มีวิธีเพิ่มเติมเพื่อเพิ่มความเร็วในการแทรก และฉันก็ใช้เกณฑ์เปรียบเทียบบางอย่าง


0

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

เอกสาร MySQL

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