การสร้างดัชนีก่อนกรอกข้อมูลในตารางจะดีกว่าหรือไม่หรือหลังจากจัดวางข้อมูลแล้ว


92

ฉันมีตารางประมาณ 100 ล้านแถวที่ฉันจะคัดลอกเพื่อแก้ไขเพิ่มดัชนี ฉันไม่ได้กังวลกับเวลาที่ต้องใช้ในการสร้างตารางใหม่ แต่ดัชนีที่สร้างขึ้นจะมีประสิทธิภาพมากขึ้นหรือไม่หากฉันแก้ไขตารางก่อนที่จะแทรกข้อมูลใด ๆ หรือแทรกข้อมูลก่อนแล้วจึงเพิ่มดัชนี

คำตอบ:


117

การสร้างดัชนีหลังจากการแทรกข้อมูลเป็นวิธีที่มีประสิทธิภาพมากขึ้น (มักจะแนะนำให้ดร็อปดัชนีก่อนนำเข้าแบทช์และหลังจากนำเข้าแล้วสร้างใหม่)

ตัวอย่าง Syntetic (PostgreSQL 9.1 เครื่องพัฒนาช้าหนึ่งล้านแถว):

CREATE TABLE test1(id serial, x integer);
INSERT INTO test1(id, x) SELECT x.id, x.id*100 FROM generate_series(1,1000000) AS x(id);
-- Time: 7816.561 ms
CREATE INDEX test1_x ON test1 (x);
-- Time: 4183.614 ms

แทรกแล้วสร้างดัชนี - ประมาณ 12 วินาที

CREATE TABLE test2(id serial, x integer);
CREATE INDEX test2_x ON test2 (x);
-- Time: 2.315 ms
INSERT INTO test2(id, x) SELECT x.id, x.id*100 FROM generate_series(1,1000000) AS x(id);
-- Time: 25399.460 ms

สร้างดัชนีแล้วแทรก - ประมาณ 25.5 วินาที (ช้ากว่าสองเท่า)


5
+1 ดัชนีจะทำให้การดำเนินการที่เกี่ยวข้องกับงานแทรกแถว 100M ช้าลงอย่างเห็นได้ชัดดังนั้นจึงควรวางและสร้างขึ้นใหม่
code4life

11

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

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


2

สิ่งนี้ไม่สำคัญกับปัญหานี้เนื่องจาก:

  1. หากคุณเพิ่มข้อมูลลงในตารางก่อนและหลังจากนั้นคุณจะเพิ่มดัชนี เวลาในการสร้างดัชนีของคุณจะO(n*log(N))นานขึ้น ( nแถวที่เพิ่มเข้ามา) เนื่องจากเวลา gerating ของต้นไม้คือO(N*log(N))ถ้าคุณแยกสิ่งนี้ออกเป็นข้อมูลเก่าและข้อมูลใหม่คุณจะได้รับO((X+n)*log(N))สิ่งนี้สามารถแปลงเป็นได้ง่าย ๆO(X*log(N) + n*log(N))และในรูปแบบนี้คุณจะเห็นสิ่งที่คุณจะรอเพิ่มเติม
  2. หากคุณเพิ่มดัชนีและหลังจากใส่ข้อมูล ทุกแถว (คุณมีnแถวใหม่) คุณจะได้รับเวลาเพิ่มเติมที่O(log(N))จำเป็นในการแทรกโครงสร้างของต้นไม้อีกต่อไปหลังจากเพิ่มองค์ประกอบใหม่เข้าไป (คอลัมน์ดัชนีจากแถวใหม่เนื่องจากมีดัชนีอยู่แล้วและมีการเพิ่มแถวใหม่ดังนั้นดัชนีจะต้องสร้างใหม่ให้สมดุล โครงสร้างค่าใช้จ่ายนี้O(log(P))ซึ่งPเป็นพลังงานดัชนี[องค์ประกอบในดัชนี] ) คุณมีnแถวใหม่แล้วในที่สุดคุณn * O(log(N))ก็O(n*log(N))สรุปเวลาเพิ่มเติมแล้ว

1

ดัชนีที่สร้างขึ้นหลังจากนั้นเร็วกว่ามากในกรณีส่วนใหญ่ ตรงประเด็น: 20 ล้านแถวที่มีข้อความเต็มใน varchar (255) - (ชื่อธุรกิจ) ดัชนีในขณะที่นำเข้าแถว - จับคู่กับการใช้เวลาสูงสุด 20 วินาทีในกรณีที่เลวร้ายที่สุด วางดัชนีและสร้างใหม่ - จับคู่กับการใช้เวลาน้อยกว่า 1 วินาทีทุกครั้ง


-2

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

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