MySQL - ทำไมไม่ทำดัชนีทุกฟิลด์?


107

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

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


7
ลองแทรกค่าลงในตารางที่มีรายการมากกว่า 10,000 รายการที่จัดทำดัชนีรายการทั้งหมดต้องได้รับการอัปเดตเนื่องจากการแทรก / ลบและนี่เป็นค่าใช้จ่ายที่มากเกินไปและค่าใช้จ่ายของหน่วยความจำส่วนหนึ่งหากแต่ละค่ามีดัชนี
Jesus Ramos

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

1
หากคุณมีตารางที่มี 30 เขตข้อมูลคุณควรดูโครงสร้างตารางของคุณจริงๆ พวกเขาควรจะทำงานหนักมาก
เว็บ

คำตอบ:


123

ดัชนีใช้พื้นที่ในหน่วยความจำ (RAM); ดัชนีมากเกินไปหรือมากเกินไปและฐานข้อมูลจะต้องมีการสลับไปยังและจากดิสก์ นอกจากนี้ยังเพิ่มเวลาในการแทรกและลบ (แต่ละดัชนีต้องได้รับการอัปเดตสำหรับข้อมูลทุกชิ้นที่แทรก / ลบ / อัปเดต)

คุณไม่มีหน่วยความจำที่ไม่มีที่สิ้นสุด ทำให้ดัชนีทั้งหมดพอดีกับ RAM = good

คุณไม่มีเวลาไม่สิ้นสุด การจัดทำดัชนีเฉพาะคอลัมน์ที่คุณต้องการจัดทำดัชนีจะช่วยลดประสิทธิภาพการแทรก / ลบ / อัปเดต Hit


11
คำตอบสบาย ๆ ที่ให้ความเข้าใจทั่วไป แต่ไม่ค่อยช่วยในการกำหนดตำแหน่งที่จะลากเส้นบนดัชนี รู้ได้ยังไง? เพียงเพิ่มลงในช่อง WHERED ทั่วไปและหวังว่าจะได้สิ่งที่ดีที่สุด
Andrew

@ อีกหนึ่งปีครึ่งต่อมาคุณพบคำตอบสำหรับคำถามของคุณหรือไม่?
สินจัย

1
@Sinjai การเพิ่มคอลัมน์เหล่านี้ลงในคอลัมน์ที่มักจะเป็นกฎง่ายๆ แต่อย่างอื่นคุณสามารถอ่านได้มากถ้าคุณต้องการเป็นผู้เชี่ยวชาญเกี่ยวกับดัชนี เช่น. stackoverflow.com/questions/3049283/…
Andrew

อย่าลืมพื้นที่ดิสก์
jpmc26

27

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

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


6
ลิงค์นี้ใช้สำหรับMS SQL Server ; คำถามนี้สำหรับMySQL
OMG Ponies

5
@OMG จุดส่วนใหญ่ในลิงค์ใช้กับ RDBMS หลัก ๆ ทั้งหมด
RichardTheKiwi

5
@Richard aka cyberkiwi: ดัชนีไม่ครอบคลุมโดย ANSI - เป็นเรื่องมหัศจรรย์ที่ผู้ขายแต่ละรายใช้คำศัพท์ที่คล้ายกัน แต่ถึงอย่างนั้นมีเพียง SQL Server และ MySQL เท่านั้นที่ใช้คำศัพท์เฉพาะดัชนี "คลัสเตอร์" และ "ไม่ใช่คลัสเตอร์" ซึ่งมีความหมายใน SQL Server มากกว่า MySQL ไม่มีสิ่งใดที่จะรับประกันได้ว่าควรนำคำแนะนำสำหรับผู้ขายรายหนึ่งไปใช้กับอีกรายหนึ่ง
OMG Ponies

3
@omg 6 คะแนนแรกใช้กับ dbms ใดก็ได้ ข้ามสิ่งที่ไม่ใช่ / คลัสเตอร์จากนั้นด้านล่างจะเป็นประเด็นเพิ่มเติมเกี่ยวกับการจัดทำดัชนีทั่วไปและตรงประเด็นด้วย หากคุณมีบางสิ่งที่ต้องการแจ้งให้โทรหาพวกเขา มิฉะนั้นดูเหมือนว่าคุณกำลังปฏิเสธคำตอบทั้งหมดที่มาจากความคิดเห็น (รวมถึงคำตอบที่ถูกลบของคุณ) ซึ่งไม่มีใครเห็นด้วยกับการประเมินของคุณ
RichardTheKiwi

10

คุณต้องปรับสมดุลความต้องการ CRUD การเขียนลงในตารางจะช้า สำหรับตำแหน่งที่จะลากเส้นนั้นขึ้นอยู่กับว่าข้อมูลถูกส่งไปอย่างไร (การกรองการเรียงลำดับ ฯลฯ )


และทุกดัชนีก็ใช้พื้นที่ฐานข้อมูล
Acanthus

@Acanthus: ฮาร์ดไดรฟ์ที่มีขนาดเล็กที่สุดที่มีอยู่ที่วัดในกิกะไบต์
OMG Ponies

4
@OMG แต่ไม่ใช่ RAM ตามที่ Brian ชี้ให้เห็น มันเป็นสิ่งที่ไม่เคยมีความคิดที่ดีในการจัดเก็บมากขึ้นกว่าที่คุณจะต้อง การแคชข้อมูล / ดัชนีใน RAM สื่อสำรอง (เวอร์ชันที่จะพอดีกับเทป ฯลฯ ) ล้วนได้รับผลกระทบจากดัชนีที่ไร้ประโยชน์
RichardTheKiwi

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

6
จริงอยู่ แต่ข้อ จำกัด ไม่ใช่สิ่งที่เมื่อ 10 ปีก่อน
OMG Ponies

2

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


2

คำตอบนี้เป็นความคิดเห็นส่วนตัวของฉันโดยใช้ตรรกะทางคณิตศาสตร์เพื่อตอบ

คำถามที่สองเกี่ยวกับเส้นขอบที่จะหยุดก่อนอื่นให้ทำการคำนวณทางคณิตศาสตร์สมมติว่าเรามี N แถวที่มีเขตข้อมูล L ในตารางถ้าเราทำดัชนีเขตข้อมูลทั้งหมดเราจะได้ตารางดัชนีใหม่ L โดยทุกตารางจะเรียงลำดับเป็น มีความหมายอย่างเต็มที่ข้อมูลของฟิลด์ดัชนีในแวบแรกถ้าตารางของคุณมีน้ำหนัก W มันจะกลายเป็น W * 2 (1 เทราจะกลายเป็น 2 เทรา) ถ้าคุณมีโต๊ะใหญ่ 100 โต๊ะ (ฉันเคยทำงานในโครงการที่หมายเลขตารางคือ ประมาณ 1800 ตาราง) คุณจะเสียพื้นที่ 100 เท่า (100 tera) ซึ่งเป็นวิธีที่ห่างไกลจากความฉลาด

หากเราจะใช้ดัชนีในตารางทั้งหมดเราจะต้องคิดเกี่ยวกับการอัปเดตดัชนีคือการอัปเดตหนึ่งทริกเกอร์การอัปเดตดัชนีทั้งหมดนี้เป็นการเลือกที่ไม่ได้เรียงลำดับตามเวลาทั้งหมด

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

ดัชนีอะไร

คีย์ต่างประเทศ: ต้องขึ้นอยู่กับ

คีย์หลัก: ฉันยังไม่แน่ใจว่าอาจมีคนอ่านสิ่งนี้สามารถช่วยในกรณีนี้ได้

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

จาก 3 จุดนี้ฉันสามารถสรุปได้ว่าถ้าเรามีฟิลด์ L ที่ประกอบด้วยคีย์ K ขีด จำกัด ควรอยู่ใกล้((L-K)/2)+Kมากหรือน้อยโดย L / 10

คำตอบนี้ขึ้นอยู่กับตรรกะและคำพูดส่วนตัวของฉัน


1

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


ฉันไม่แน่ใจว่ามันจะทำให้การอ่านตารางเป็นไปอย่างรวดเร็วโดยเฉพาะอย่างยิ่งถ้า data-table มีขนาดเพียง 100MB แต่ index.table 300MB ขึ้นไป
David

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