มีวิธีที่เป็นระบบในการบังคับให้ PostgreSQL โหลดตารางเฉพาะลงในหน่วยความจำหรืออย่างน้อยก็อ่านจากดิสก์เพื่อให้ระบบถูกแคชหรือไม่
มีวิธีที่เป็นระบบในการบังคับให้ PostgreSQL โหลดตารางเฉพาะลงในหน่วยความจำหรืออย่างน้อยก็อ่านจากดิสก์เพื่อให้ระบบถูกแคชหรือไม่
คำตอบ:
คุณอาจถูกขัดจังหวะในหัวข้อหนึ่งในรายชื่อรับเมลมันตอบโดย Tom Lane (คอร์ dev):
[.. ] แต่ความคิดเห็นของฉันคือคนที่คิดว่าฉลาดกว่าอัลกอริธึมการแคช LRU มักเข้าใจผิด หากตารางทั้งหมดที่ใช้อย่างหนักก็จะอยู่ในหน่วยความจำได้ดี ถ้ามันไม่ได้ใช้อย่างหนักพอที่จะอยู่ในหน่วยความจำตามอัลกอริธึม LRU บางทีพื้นที่หน่วยความจำควรใช้กับอย่างอื่น [ .. ]
คุณอาจถูกขัดจังหวะด้วยคำถาม SO: https://stackoverflow.com/questions/486154/postgresql-temporary-tablesและhttps://stackoverflow.com/questions/407006/need-to-load-the -whole-PostgreSQL ฐานข้อมูลลงในที่แกะ
ในที่สุดPostgres 9.4ก็เพิ่มส่วนขยายเพื่อโหลดข้อมูลล่วงหน้าจากความสัมพันธ์ลงในระบบปฏิบัติการหรือแคชบัฟเฟอร์ฐานข้อมูล (ตามที่คุณต้องการ):
pg_prewarm
สิ่งนี้ทำให้การทำงานเต็มประสิทธิภาพรวดเร็วยิ่งขึ้น
รันหนึ่งครั้งในฐานข้อมูลของคุณ (คำแนะนำโดยละเอียดที่นี่ ):
CREATE EXTENSION pg_prewarm;
จากนั้นง่าย ๆ ในการโหลดล่วงหน้าความสัมพันธ์ที่กำหนด ตัวอย่างพื้นฐาน:
SELECT pg_prewarm('my_tbl');
ค้นหาตารางแรกที่มีชื่อmy_tbl
ในพา ธ การค้นหาและโหลดไปยังแคชบัฟเฟอร์ Postgres
หรือ:
SELECT pg_prewarm('my_schema.my_tbl', 'prefetch');
prefetch
ส่งคำขอการดึงข้อมูลล่วงหน้าแบบอะซิงโครนัสไปยังระบบปฏิบัติการหากได้รับการสนับสนุนหรือส่งข้อผิดพลาดเป็นอย่างอื่นread
อ่านช่วงของบล็อกที่ร้องขอ ซึ่งแตกต่างจากprefetch
นี้เป็นแบบซิงโครนัสและสนับสนุนในทุกแพลตฟอร์มและงานสร้าง แต่อาจช้ากว่าbuffer
อ่านช่วงที่ร้องขอของบล็อกลงในแคชบัฟเฟอร์ฐานข้อมูล
ค่าเริ่มต้นคือbuffer
ซึ่งมีผลกระทบมากที่สุด (ค่าใช้จ่ายสูงกว่าผลที่ดีที่สุด)
อ่านคู่มือสำหรับรายละเอียดเพิ่มเติมใบเสนอราคามาจากที่นั่น
Depesz bloggedเกี่ยวกับมันเช่นกัน
ในกรณีทั่วไปถ้าคุณมีแรมเพียงพอคุณสามารถเชื่อถือบริการฐานข้อมูลโดยทั่วไปเพื่อทำงานที่ดีในการรักษาสิ่งต่าง ๆ ที่คุณใช้เป็นประจำใน RAM ระบบบางระบบอนุญาตให้คุณบอกใบ้ว่าตารางควรอยู่ใน RAM เสมอ (ซึ่งมีประโยชน์สำหรับตารางเล็ก ๆ ที่ไม่ได้ใช้บ่อย แต่เมื่อมีการใช้งานเป็นสิ่งสำคัญที่จะต้องตอบสนองโดยเร็วที่สุด) แต่ถ้า pgsql มีคำแนะนำตารางดังกล่าว คุณต้องระมัดระวังอย่างมากเกี่ยวกับการใช้สิ่งเหล่านี้ขณะที่คุณลดจำนวนหน่วยความจำที่มีอยู่สำหรับการแคชสิ่งอื่นดังนั้นคุณอาจทำให้แอปพลิเคชันของคุณช้าลง
หากคุณกำลังมองหาแคชของฐานข้อมูลที่สำคัญเมื่อเริ่มต้น (เช่นหลังจากรีบูตหรือการดำเนินการบำรุงรักษาอื่น ๆ ที่ทำให้ DB ลืมทุกอย่างที่แคช) ให้เขียนสคริปต์ที่ทำสิ่งต่อไปนี้:
SELECT * FROM <table>
SELECT <primary key fields> FROM <table> ORDER BY <primary key fields>
SELECT <indexed fields> FROM <table> ORDER BY <indexed fields>
(ขั้นตอนสุดท้ายนั้นซ้ำสำหรับแต่ละดัชนีหรือหลักสูตรและโปรดระมัดระวังในการมีฟิลด์ในส่วนคำสั่งซื้อตามลำดับที่ถูกต้อง)
หลังจากเรียกใช้ข้อมูลข้างต้นทุกหน้าและดัชนีควรอ่านแล้วและจะอยู่ในแคชหน้า RAM (สำหรับเวลาอย่างน้อย) เรามีสคริปต์เช่นนี้สำหรับฐานข้อมูลแอปพลิเคชันของเราซึ่งทำงานหลังจากรีบูตเพื่อให้ผู้ใช้รายแรกเข้าสู่ระบบหลังจากนั้นไม่ตอบสนองช้าลง คุณควรเขียนสคริปต์ดังกล่าวด้วยตัวเองแทนที่จะสแกนตารางคำนิยาม db (เช่นsys.objects
/ sys.indexes
/ sys.columns
ใน MSSQL) จากนั้นคุณสามารถเลือกสแกนดัชนีที่ใช้บ่อยที่สุดแทนที่จะสแกนทุกอย่างที่ใช้เวลานานกว่า
SELECT * FROM schema.table
และดูว่าโหลดตาราง 60GiB ทั้งหมดลงในแคชบัฟเฟอร์ 100GiB PostgreSQL ของฉัน
ฉันมีปัญหาที่คล้ายกัน:
หลังจากรีสตาร์ทบริการเซิร์ฟเวอร์และข้อมูลแคชทั้งหมดลดลงแบบสอบถามจำนวนมากเรียกครั้งแรกที่จริงๆช้ามากสาเหตุของความซับซ้อนเฉพาะของแบบสอบถามจนกระทั่งดัชนีและข้อมูลที่จำเป็นทั้งหมดได้รับเงิน นั่นหมายความว่าตัวอย่างเช่นผู้ใช้จะต้องกด "รายการ" ทุกครั้ง (1-3 วินาทีในการประมวลผลครั้ง) และข้อมูลที่เกี่ยวข้องจาก 50 ล้านแถวดังนั้นผู้ใช้จะไม่ประสบกับความล่าช้าที่ไม่ต้องการอีกต่อไป มันใช้เวลา 3 ชั่วโมงแรกสำหรับผู้ใช้ที่จะพบกับการแฮงค์ที่น่ารำคาญจนกระทั่งข้อมูลที่ใช้ส่วนใหญ่เป็นเงินสดและโปรแกรมกำลังทำลายรอยบนสุดด้วยประสิทธิภาพการผลิตสิ้นสุดลงหลังจากนั้น 2 วันความล่าช้าสั้น ๆ ทันทีสองสามครั้ง สำหรับข้อมูลสถิติ ฯลฯ
เพื่อแก้ปัญหานี้ให้เขียนสคริปต์ python ขนาดเล็กซึ่งทำการเลือกบนตารางที่ใช้มากที่สุดที่มีดัชนีขนาดใหญ่ ใช้เวลา 15 นาทีในการทำงานและไม่มีประสิทธิภาพล่าช้า
อืมคำสั่ง COPY อาจจะช่วยได้ เพียงดำเนินการคัดลอกเพื่อ stdout และอ่านจากมัน เป็นไปได้ที่จะใช้ pg_dump:
pg_dump -U <user> -t <table> <database> > /dev/null
วิธีอื่น ๆ cat <files> > /dev/null
คือการหาไฟล์ตารางทั้งหมดและเรียกใช้
นี่คือตัวอย่างเกี่ยวกับวิธีรับชื่อไฟล์ของตาราง:
# SELECT oid, datname FROM pg_database ;
oid | datname
-------+-----------
<...>
16384 | test
-- out of database is 16384
# SELECT oid, relname FROM pg_class WHERE relname like 'fn%';
oid | relname
-------+---------
24576 | fn
(1 row)
-- oid of our table is 24576
ดังนั้นไฟล์ของตารางคือ / path / to / pgsql / data / base / 16384/24576 *
คุณต้องการที่จะอ่านดัชนีและตารางขนมปังปิ้งเช่นกันรับ oids ของพวกเขาในลักษณะเดียวกัน
BTW ทำไมคุณต้องการมัน ฉันเชื่อว่า postgresql และระบบปฏิบัติการนั้นฉลาดพอที่จะแคชข้อมูลที่ร้อนแรงและรักษาได้ดี ประสิทธิภาพแคช
ฉันใช้RamDriveจาก QSoft ซึ่งเป็นเกณฑ์มาตรฐานว่าเป็น ramdisk ที่เร็วที่สุดสำหรับ Windows ฉันเพิ่งใช้
initdb -D e:\data
โดยที่ e: \ เป็นที่ตั้งของ RamDisk