สิ่งที่ดึงมาจากดิสก์ในระหว่างการสืบค้น?


14

คำถามธรรมดาค่อนข้างน่าจะมีคำตอบอยู่บ้าง แต่ฉันไม่สามารถสร้างคำถามค้นหาที่เหมาะสมสำหรับ Google ...

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

ตัวอย่างเช่นหากตาราง Foo มี 20 คอลัมน์ แต่แบบสอบถามของฉันเลือกเพียง 5 คอลัมน์เหล่านั้นจะมีคอลัมน์ 20 (เทียบกับพูด 10) มีผลต่อประสิทธิภาพการค้นหาหรือไม่ สมมติว่าความเรียบง่ายนั้นมีอะไรรวมอยู่ใน WHERE clause ในคอลัมน์ 5 คอลัมน์เหล่านั้น

ฉันกังวลเกี่ยวกับการใช้แคชบัฟเฟอร์ของ Postgres นอกเหนือจากดิสก์แคชของระบบปฏิบัติการ ฉันไม่เข้าใจการออกแบบที่จัดเก็บข้อมูลจริงของ Postgres ตารางถูกเก็บไว้ในหลาย ๆ หน้า (ขนาดเริ่มต้นที่ 8k ต่อหน้า) แต่ฉันไม่เข้าใจว่าจะมีการจัดเรียงทูเปิลอย่างไร PG ฉลาดพอที่จะดึงข้อมูลจากดิสก์ที่ประกอบด้วยคอลัมน์ 5 คอลัมน์เหล่านั้นได้หรือไม่


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

คุณรับหมายเลขเหล่านั้นจากที่ไหน
Jmoney38

คำตอบ:


15

จัดเก็บข้อมูลทางกายภาพสำหรับแถวอธิบายไว้ในเอกสารที่อยู่ในฐานข้อมูลการออกแบบหน้าเว็บ เนื้อหาคอลัมน์สำหรับแถวเดียวกันทั้งหมดถูกเก็บไว้ในหน้าดิสก์เดียวกันโดยมีข้อยกเว้นที่เด่นชัดของเนื้อหา ed ของTOAST (มีขนาดใหญ่เกินกว่าจะใส่ในหน้าได้) เนื้อหาจะถูกแยกตามลำดับภายในแต่ละแถวดังที่อธิบายไว้:

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

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

ตอนนี้กรณี TOAST: เมื่อแต่ละเขตข้อมูลเกิน ~ 2kB เครื่องยนต์เก็บเนื้อหาของเขตข้อมูลลงในตารางทางกายภาพแยกต่างหาก นอกจากนี้ยังมีการเล่นเมื่อทั้งแถวไม่พอดีกับหน้าเว็บ (โดยค่าเริ่มต้น 8kB): บางฟิลด์ถูกย้ายไปยังที่เก็บข้อมูลของ TOAST หมอพูดว่า:

หากเป็นฟิลด์ความยาวผันแปร (attlen = -1) แสดงว่ามันซับซ้อนกว่าเล็กน้อย ชนิดข้อมูลที่มีความยาวผันแปรได้แบ่งใช้ varlena โครงสร้างส่วนหัวทั่วไปซึ่งรวมถึงความยาวทั้งหมดของค่าที่เก็บไว้และบิตธงบางส่วน ข้อมูลอาจเป็นแบบอินไลน์หรือในตาราง TOAST ทั้งนี้ขึ้นอยู่กับแฟล็ก มันอาจถูกบีบอัดด้วย

เนื้อหาของ TOAST จะไม่ถูกดึงออกมาเมื่อไม่ต้องการอย่างชัดเจนดังนั้นผลกระทบที่มีต่อจำนวนหน้าทั้งหมดในการดึงข้อมูลมีขนาดเล็ก (ไม่กี่ไบต์ต่อคอลัมน์) สิ่งนี้จะอธิบายผลลัพธ์ในคำตอบของ @ dezso

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


นั่นคือคำตอบที่เตะตูด สิ่งที่ฉันกำลังมองหา ขอขอบคุณ.
Jmoney38

1
ทรัพยากรที่ดีผมพบว่าในเรื่องที่เกี่ยวกับโครงสร้างแถว (pageinspect และบางการใช้งานตัวอย่าง) ที่นี่
Jmoney38

10

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

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

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

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

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

มันอาจจะหรืออาจจะไม่สำคัญว่าถ้าคอลัมน์ที่ไม่เกี่ยวข้อง TOAST-ED คอลัมน์ที่เกี่ยวข้องอาจเป็น TOAST-ed เช่นกันซึ่งจะนำเอฟเฟกต์เดียวกันกลับมามากมาย


1

การทดสอบขนาดเล็ก:

CREATE TABLE test2 (
    id serial PRIMARY KEY,
    num integer,
    short_text varchar(32),
    longer_text varchar(1000),
    long_long_text text
);

INSERT INTO test2 (num, short_text, longer_text, long_long_text)
SELECT i, lpad('', 32, 'abcdefeghji'), lpad('', 1000, 'abcdefeghji'), lpad('', (random() * 10000)::integer, 'abcdefeghji')
FROM generate_series(1, 10000) a(i);

ANALYZE test2;

SELECT * FROM test2;
[...]
Time: 1091.331 ms

SELECT num FROM test2;
[...]
Time: 21.310 ms

การ จำกัดWHERE num <= 250คิวรีให้อยู่ในแถวแรก 250 แถว ( ) ให้ผลลัพธ์เป็น 34.539 ms และ 8.343 ms ตามลำดับ การเลือกทั้งหมดยกเว้นlong_long_textชุดที่ จำกัด นี้จะให้ผลลัพธ์เป็น 18.432 ms นี่แสดงให้เห็นว่าในแง่ของคุณ PG นั้นฉลาดพอ


ฉันชื่นชมการป้อนข้อมูลอย่างแน่นอน อย่างไรก็ตามฉันไม่สามารถพูดด้วยความมั่นใจว่าสถานการณ์การทดสอบนี้พิสูจน์สิ่งที่ฉันเสนอมา มีปัญหาเล็กน้อย สำหรับหนึ่งเมื่อคุณรัน "SELECT * FROM test2" ครั้งแรกนั่นควรจะเต็มแคชบัฟเฟอร์ที่ใช้ร่วมกันของคุณ แบบสอบถามนั้นจะใช้เวลาในการเรียกคืนจากดิสก์นานขึ้น ดังนั้นคำถามที่ 2 ในทางทฤษฎีจะเร็วกว่ามากเนื่องจากจะดึงข้อมูลจากแคช SB แต่ฉันยอมรับว่า 'แนะนำ' ว่า PG ดึงเฉพาะแถวที่ต้องการเท่านั้นโดยขึ้นอยู่กับการทดสอบ / การเปรียบเทียบในภายหลังของคุณ
Jmoney38

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