Caveat: อาจมีความไม่ถูกต้องด้านล่าง ฉันได้เรียนรู้เกี่ยวกับสิ่งนี้มากมายเมื่อฉันไปพร้อมกับเกลือ นี่ค่อนข้างนาน แต่คุณสามารถอ่านพารามิเตอร์ที่เราเล่นด้วยจากนั้นข้ามไปที่บทสรุปในตอนท้าย
มีหลายเลเยอร์ที่คุณสามารถกังวลเกี่ยวกับประสิทธิภาพการเขียนของ SQLite:
เราดูสิ่งที่ถูกเน้นเป็นตัวหนา พารามิเตอร์เฉพาะคือ
- แคชเขียนดิสก์ ดิสก์ที่ทันสมัยมีแคช RAM ซึ่งใช้ในการเพิ่มประสิทธิภาพการเขียนดิสก์ตามดิสก์หมุน ด้วยการเปิดใช้งานนี้ข้อมูลสามารถเขียนในบล็อกที่ไม่เรียบร้อยดังนั้นหากเกิดความผิดพลาดคุณสามารถจบลงด้วยไฟล์ที่เขียนบางส่วน ตรวจสอบการตั้งค่าด้วย hdparm -W / dev / ... และตั้งค่าด้วย hdparm -W1 / dev / ... (เพื่อเปิดใช้งานและ -W0 เพื่อปิด)
- อุปสรรค = (0 | 1) ความคิดเห็นออนไลน์จำนวนมากพูดว่า "ถ้าคุณทำงานด้วย barrier = 0 ดังนั้นอย่าเปิดใช้งานแคชการเขียนดิสก์" คุณสามารถค้นหาการอภิปรายเกี่ยวกับอุปสรรคได้ที่http://lwn.net/Articles/283161/
- data = (เจอร์นัล | สั่ง | writeback) ดูhttp://www.linuxtopia.org/HowToGuides/ext3JournalingFilesystem.htmlเพื่อดูคำอธิบายของตัวเลือกเหล่านี้
- กระทำ = N บอก ext3 เพื่อซิงค์ข้อมูลและข้อมูลเมตาทุก N วินาที (ค่าเริ่มต้น 5)
- SQLite pragma synchronous = ON | ปิด เมื่อเปิด SQLite จะตรวจสอบให้แน่ใจว่าการทำธุรกรรมเป็น "เขียนไปยังดิสก์" ก่อนดำเนินการต่อ การปิดการตั้งค่านี้ทำให้การตั้งค่าอื่น ๆ ไม่เกี่ยวข้องเป็นอย่างมาก
- SQLite pragma cache_size ควบคุมจำนวนหน่วยความจำ SQLite ที่จะใช้สำหรับแคชในหน่วยความจำ ฉันลองสองขนาด: หนึ่งที่ฐานข้อมูลทั้งหมดจะพอดีกับแคชและที่หนึ่งซึ่งแคชนั้นมีขนาดครึ่งหนึ่งของขนาด DB สูงสุด
อ่านข้อมูลเพิ่มเติมเกี่ยวกับตัวเลือก ext3 ในเอกสาร ext3
ฉันรันการทดสอบประสิทธิภาพกับชุดค่าผสมหลายตัวของพารามิเตอร์เหล่านี้ ID คือหมายเลขสถานการณ์อ้างอิงตามด้านล่าง
ฉันเริ่มต้นด้วยการรันด้วยการกำหนดค่าเริ่มต้นบนเครื่องของฉันเป็นสถานการณ์ที่ 1 สถานการณ์ที่ 2 คือสิ่งที่ฉันคิดว่าเป็น "ปลอดภัยที่สุด" จากนั้นลองใช้ชุดค่าผสมต่าง ๆ ตามความเหมาะสม / ได้รับข้อความ นี่อาจจะง่ายที่สุดในการทำความเข้าใจกับแผนที่ที่ฉันใช้:
ฉันเขียนสคริปต์ทดสอบที่ทำธุรกรรมจำนวนมากโดยมีการแทรกการอัปเดตและการลบทั้งหมดอยู่ในตารางที่มีทั้ง INTEGER เท่านั้น, TEXT เท่านั้น (พร้อมคอลัมน์ id) หรือผสม ฉันใช้จำนวนครั้งนี้ในการกำหนดค่าแต่ละอย่างด้านบน:
สถานการณ์สองสถานการณ์ด้านล่างคือ # 6 และ # 17 ซึ่งมี "pragma synchronous = off" ดังนั้นไม่น่าแปลกใจเลยที่พวกเขาจะเร็วที่สุด คลัสเตอร์ถัดไปของสามคือ # 7, # 11 และ # 19 สามสิ่งนี้ถูกเน้นด้วยสีน้ำเงินบน "แผนที่การกำหนดค่า" ด้านบน โดยพื้นฐานแล้วการกำหนดค่าคือแคชการเขียนดิสก์, barrier = 0 และชุดข้อมูลเป็นสิ่งอื่นที่ไม่ใช่ 'journal' การเปลี่ยนการมอบหมายระหว่าง 5 วินาที (# 7) และ 60 วินาที (# 11) ดูเหมือนจะสร้างความแตกต่างเล็กน้อย ในการทดสอบเหล่านี้ดูเหมือนจะไม่มากถ้าความแตกต่างระหว่าง data = สั่งและ data = writeback ซึ่งทำให้ฉันประหลาดใจ
การทดสอบการอัพเดทแบบผสมคือจุดสูงสุดตรงกลาง มีกลุ่มของสถานการณ์ที่ชัดเจนช้ากว่าในการทดสอบนี้ เหล่านี้เป็นคนทั้งหมดที่มีข้อมูล = วารสาร มิฉะนั้นจะมีอะไรไม่มากระหว่างสถานการณ์อื่น ๆ
ฉันมีการทดสอบเวลาอื่นซึ่งทำให้เม็ดมีดที่แตกต่างกันมากขึ้นอัปเดตและลบในการผสมประเภทต่างๆ สิ่งเหล่านี้ใช้เวลานานกว่ามากซึ่งเป็นสาเหตุที่ฉันไม่ได้รวมไว้ในแผนด้านบน:
ที่นี่คุณจะเห็นว่าการกำหนดค่าการเขียนกลับ (# 19) ช้ากว่าการสั่งซื้อ (# 7 และ # 11) เล็กน้อย ฉันคาดว่าการเขียนกลับจะเร็วขึ้นเล็กน้อย แต่อาจขึ้นอยู่กับรูปแบบการเขียนของคุณหรือบางทีฉันอาจจะยังไม่อ่าน ext3 มากพอ :-)
สถานการณ์ต่างๆเป็นตัวแทนของการดำเนินการที่กระทำโดยแอปพลิเคชันของเรา หลังจากเลือกรายการสั้น ๆ ของสถานการณ์เราทำการทดสอบเวลาด้วยชุดทดสอบอัตโนมัติบางชุด พวกเขาสอดคล้องกับผลลัพธ์ข้างต้น
ข้อสรุป
- กระทำพารามิเตอร์ดูเหมือนจะสร้างความแตกต่างเล็ก ๆ น้อย ๆ เพื่อให้เรากำลังจะออกจากที่ที่ 5s
- เรากำลังจะมีการเขียนดิสก์แคชบนอุปสรรค = 0และข้อมูล = สั่งซื้อ ฉันอ่านบางสิ่งออนไลน์ที่คิดว่านี่เป็นการตั้งค่าที่ไม่ดีและอื่น ๆ ที่ดูเหมือนว่าจะคิดว่านี่เป็นค่าเริ่มต้นในหลาย ๆ สถานการณ์ ฉันเดาว่าสิ่งที่สำคัญที่สุดคือคุณต้องตัดสินใจอย่างชาญฉลาดโดยรู้ว่าการแลกเปลี่ยนใดที่คุณกำลังทำอยู่
- เราจะไม่ใช้ pragma แบบซิงโครนัสใน SQLite
- การตั้งค่า SQLite cache_size pragma ดังนั้นฐานข้อมูลจะพอดีกับหน่วยความจำที่ปรับปรุงประสิทธิภาพการทำงานบางอย่างตามที่เราคาดไว้
- การกำหนดค่าข้างต้นหมายความว่าเรามีความเสี่ยงเพิ่มขึ้นเล็กน้อย เราจะใช้SQLite backup APIเพื่อลดอันตรายจากความล้มเหลวของดิสก์ในการเขียนบางส่วน: ถ่ายภาพทุกๆ N นาทีและเก็บ M สุดท้ายไว้ ฉันทดสอบ API นี้ขณะใช้การทดสอบประสิทธิภาพและทำให้เรามั่นใจในการใช้วิธีนี้
- หากเรายังต้องการมากกว่านี้เราสามารถดูการล้อเลียนด้วยเคอร์เนล แต่เราปรับปรุงสิ่งต่าง ๆ ให้ดีพอโดยไม่ต้องไปที่นั่น
ขอบคุณ @Huygens สำหรับเคล็ดลับและคำแนะนำต่างๆ