ดัชนีคอลัมน์เดียวสองรายการเทียบกับดัชนีสองคอลัมน์หนึ่งรายการใน MySQL?


114

ฉันต้องเผชิญกับสิ่งต่อไปนี้และไม่แน่ใจว่าแนวทางปฏิบัติที่ดีที่สุดคืออะไร

พิจารณาตารางต่อไปนี้ (ซึ่งจะมีขนาดใหญ่):

id PK | giver_id FK | ผู้รับ _id FK | วันที่

ฉันใช้ InnoDB และจากสิ่งที่ฉันเข้าใจมันสร้างดัชนีโดยอัตโนมัติสำหรับคอลัมน์คีย์ต่างประเทศสองคอลัมน์ อย่างไรก็ตามฉันจะทำการค้นหามากมายที่ฉันต้องการจับคู่ชุดค่าผสมเฉพาะของ:

SELECT...WHERE giver_id = x AND recipient_id = t.

ชุดค่าผสมแต่ละชุดจะไม่ซ้ำกันในตาราง

มีประโยชน์จากการเพิ่มดัชนีสองคอลัมน์บนคอลัมน์เหล่านี้หรือไม่หรือดัชนีสองตัวในทางทฤษฎีจะเพียงพอ / เหมือนกันหรือไม่?


1
หากการรวมกันของสองคอลัมน์ไม่ซ้ำกันคุณสามารถสร้างดัชนีสองคอลัมน์ที่มีคุณลักษณะเฉพาะซึ่งไม่เพียงเพิ่มความเร็วในการสืบค้นของคุณ แต่ยังเพิ่มความสอดคล้องให้กับตารางของคุณด้วย
sguven

"MySQL สามารถใช้ดัชนีหลายคอลัมน์สำหรับแบบสอบถามที่ทดสอบคอลัมน์ทั้งหมดในดัชนีหรือแบบสอบถามที่ทดสอบเฉพาะคอลัมน์แรกสองคอลัมน์แรกสามคอลัมน์แรกเป็นต้นหากคุณระบุคอลัมน์ทางด้านขวา ลำดับในนิยามดัชนีดัชนีคอมโพสิตเดียวสามารถเร่งความเร็วของการสืบค้นหลายประเภทบนตารางเดียวกันได้ " - ดัชนีหลายคอลัมน์
AlikElzin-kilaka

เพื่อคาดการณ์ใน @ user1585784; ถ้าการรวมกันของสองคอลัมน์ไม่ซ้ำกันฉันคิดว่าควรใช้คีย์ที่ไม่ซ้ำกันสำหรับคอลัมน์เหล่านี้ ในความเป็นจริงถ้าใครต้องการบังคับใช้ความเป็นเอกลักษณ์ในระดับฐานข้อมูลคีย์เฉพาะเป็นวิธีที่ง่ายที่สุด ...
เอิร์ก

คำตอบ:


133

หากคุณมีดัชนีคอลัมน์เดียวสองรายการจะใช้เพียงดัชนีเดียวในตัวอย่างของคุณ

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

บางครั้งการมีดัชนีบน (A, B) และดัชนีอื่นบน (B) อาจเป็นประโยชน์ สิ่งนี้ทำให้การสืบค้นโดยใช้คอลัมน์ใดคอลัมน์หนึ่งหรือทั้งสองคอลัมน์ทำได้รวดเร็ว แต่แน่นอนว่ายังใช้พื้นที่ดิสก์มากขึ้นด้วย

เมื่อเลือกดัชนีคุณต้องพิจารณาผลกระทบในการแทรกการลบและการอัปเดตด้วย ดัชนีเพิ่มเติม = อัปเดตช้าลง


1
"MySQL สามารถใช้ดัชนีหลายคอลัมน์สำหรับแบบสอบถามที่ทดสอบคอลัมน์ทั้งหมดในดัชนีหรือแบบสอบถามที่ทดสอบเฉพาะคอลัมน์แรกสองคอลัมน์แรกสามคอลัมน์แรกเป็นต้นหากคุณระบุคอลัมน์ทางด้านขวา ลำดับในนิยามดัชนีดัชนีคอมโพสิตเดียวสามารถเร่งความเร็วของการสืบค้นหลายประเภทบนตารางเดียวกันได้ " - ดัชนีหลายคอลัมน์
AlikElzin-kilaka

33

ดัชนีครอบคลุมเช่น:

ALTER TABLE your_table ADD INDEX (giver_id, recipient_id);

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

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


10
MySQL can only use one index per SELECTสิ่งนี้ไม่เป็นความจริงอีกต่อไปคงจะดีถ้าคุณแก้ไขคำตอบของคุณให้อัปเดต
Davor

คุณจะคิดที่จะอธิบายว่าทำไมดัชนีครอบคลุมจะไม่สามารถที่จะนำมาใช้โดยrecipient_id?
Ivo Pereira

2
@IvoPereira ดัชนีหลายคอลัมน์ใน MySQL ช่วยให้คุณใช้ฟิลด์ทั้งหมดในดัชนีจากซ้ายไปขวา ตัวอย่างเช่นหากคุณมีINDEX (col1, col2, col3, col4)ดัชนีจะถูกนำไปใช้กับการค้นหาที่มีWHEREอนุประโยคเช่นcol1 = 'A'หรือcol1 = 'A' AND col2 = 'B'หรือcol1 = 'A' AND col2 ='B' AND col3 = 'C' AND col4 = 'D'แต่ดัชนีเฉพาะนี้จะไม่ถูกใช้สำหรับสิ่งที่เหมือนWHERE col2 = 'B'หรือWHERE col3 = 'C' AND col4 = 'D'เนื่องจากไม่เหลือช่องค้นหามากที่สุดในนิยามดัชนี คุณจะต้องเพิ่มดัชนีเพิ่มเติมเพื่อให้ครอบคลุมฟิลด์เหล่านั้น
Slicktrick

"one index ต่อ SELECT"ยังคงเป็นจริงสำหรับ mariadb 10.1 หรือไม่
oldboy

1
@Anthony: ไม่เห็นความคิดเห็นของ Davor ด้านบน
kapad

4

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

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


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

2

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


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