PostgreSQL แตกต่างระหว่าง VACUUM FULL และ CLUSTER


13

ฉันมีตารางที่มีข้อมูลขนาด 200 GB และมีขนาด 180 GB โดยดัชนี 6 รายการ มันบวม 30% ดังนั้นฉันต้องการเรียกคืนพื้นที่ที่ไม่ต้องการครอบครอง มันเป็นคลัสเตอร์ในjob_id_idดัชนี x

ดังนั้นเพื่อเรียกคืนพื้นที่ฉันต้องใช้clusterคำสั่งหรือvacuum fullคำสั่ง?

  1. ความแตกต่างระหว่างสองคำสั่งนี้คืออะไร?

  2. คือvacuum fullการสั่งซื้อตามคอลัมน์บางเช่นเดียวกับclusterคำสั่ง?

  3. ดัชนีถูกสร้างขึ้นใหม่ทั้งในคำสั่งหรือไม่?

  4. ในกรณีของฉันอันไหนจะเร็วกว่ากัน?

เวอร์ชันของฐานข้อมูล PostgreSQL คือ 9.1


1
ใช่ดัชนีจะถูกสร้างขึ้นใหม่ ซึ่งเร็วกว่านั้นขึ้นอยู่กับสองสามอย่างฉันคิดว่า แต่สิ่งหนึ่งที่แน่นอนคือไม่มีอะไรเหมือน 'คำสั่งสูญญากาศแบบเต็มโดยบางคอลัมน์'
dezso

1
ให้ฉันพูดถึงว่าสูญญากาศไม่สามารถทำงานในการทำธุรกรรมซึ่งในหลายกรณีทำให้ CLUSTER เป็นทางเลือกที่ดีกว่า (และบางครั้งเป็นทางเลือกเดียว) ที่ให้ผลลัพธ์ที่คล้ายกัน
o

คำตอบ:


8

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

ก่อนอื่นวิ่งVACUUM FULLบนโต๊ะfkaฉันเอาขนาดของมัน:

\dt+ fka
                    List of relations
 Schema | Name | Type  |  Owner   |  Size  | Description 
--------+------+-------+----------+--------+-------------
 public | fka  | table | test     | 338 MB | 

จากนั้นเราจะดูลำดับทางกายภาพของข้อมูลจากจุดเริ่มต้นของตาราง:

SELECT *, ctid FROM fka ORDER BY ctid LIMIT 5;

 id  | col1 |  ctid   
-----+------+---------
   2 | 2    | (0,1)
   3 | 3    | (0,2)
   4 | 4    | (0,3)
   5 | 5    | (0,4)
   6 | 6    | (0,5)

ทีนี้ลองลบบางแถว:

DELETE FROM fka WHERE id % 10 = 5;
--DELETE 1000000

หลังจากนี้ขนาดของตารางที่รายงานจะไม่เปลี่ยนแปลง ดังนั้นเรามาดูกันว่าตอนนี้CLUSTERทำอะไร:

CLUSTER fka USING fka_pkey;

SELECT *, ctid FROM fka ORDER BY ctid LIMIT 5;

 id  | col1 |  ctid   
-----+------+---------
   2 | 2    | (0,1)
   3 | 3    | (0,2)
   4 | 4    | (0,3)
   6 | 6    | (0,4)
   7 | 7    | (0,5)

ขนาดตารางเปลี่ยนจาก 338 เป็น 296 MB จากctidคอลัมน์ซึ่งอธิบายถึงสถานที่ทางกายภาพของ tuple ในหน้าคุณจะเห็นว่าไม่มีช่องว่างในการจับคู่แถวที่id = 5เคยเป็น

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

ดังนั้นความแตกต่างดูเหมือนจะVACUUM FULLไม่เรียงลำดับแถว เท่าที่ฉันรู้มีความแตกต่างบางอย่างในกลไกที่ทั้งสองใช้คำสั่ง แต่จากมุมมองของการปฏิบัตินี้ดูเหมือนว่าจะเป็นความแตกต่างหลัก (เท่านั้น?)


ฉันไม่แน่ใจว่าctidคอลัมน์คืออะไร ปรากฎว่ามันเป็นคอลัมน์ระบบที่อธิบายถึงตำแหน่งทางกายภาพของแถวภายในตาราง postgresql.org/docs/current/ddl-system-columns.html
Gajus

8

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

http://www.postgresql.org/docs/9.1/static/sql-vacuum.html

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

http://www.postgresql.org/docs/9.1/static/sql-cluster.html

ที่น่าสนใจเช่นกัน: is-a-reindex-required-after-cluster

แต่บางทีสิ่งที่คุณต้องการคือการREINDEXสร้างดัชนีใหม่โดยใช้ข้อมูลที่เก็บไว้ในตารางดัชนีแทนที่สำเนาเก่าของดัชนี

http://www.postgresql.org/docs/9.1/static/sql-reindex.html


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