โดยทั่วไปคอลัมน์ใดที่สร้างดัชนีที่ดี


100

จากการติดตามผล " ดัชนีคืออะไรและฉันจะใช้เพื่อเพิ่มประสิทธิภาพการสืบค้นในฐานข้อมูลของฉันได้อย่างไร " ที่ฉันกำลังพยายามเรียนรู้เกี่ยวกับดัชนีคอลัมน์ใดบ้างที่เป็นดัชนีที่ดี โดยเฉพาะสำหรับฐานข้อมูล MS SQL?

หลังจาก googling แล้วทุกสิ่งที่ฉันได้อ่านชี้ให้เห็นว่าคอลัมน์ที่โดยทั่วไปเพิ่มขึ้นและไม่ซ้ำกันทำให้ดัชนีที่ดี (เช่นการเพิ่มอัตโนมัติของ MySQL) ฉันเข้าใจสิ่งนี้ แต่ฉันใช้ MS SQL และฉันใช้ GUID สำหรับคีย์หลักดังนั้นดูเหมือนว่า ดัชนีนั้นจะไม่เป็นประโยชน์ต่อคอลัมน์ GUID ...


"ตำราอาหาร" เป็นอย่างไรบ้าง
Rick James

คำตอบ:


113

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

SELECT
 buyer_id /* no need to index */
FROM buyers
WHERE first_name='Tariq' /* consider to use index */
AND last_name='Iqbal'   /* consider to use index */

เนื่องจากมีการอ้างอิง "buyer_id" ในส่วน SELECT จึงไม่ใช้ MySQL เพื่อ จำกัด แถวที่เลือก ดังนั้นจึงไม่จำเป็นต้องจัดทำดัชนี ด้านล่างนี้เป็นอีกตัวอย่างหนึ่งที่แตกต่างจากตัวอย่างข้างต้นเล็กน้อย:

SELECT
 buyers.buyer_id, /* no need to index */
 country.name    /* no need to index */
FROM buyers LEFT JOIN country
ON buyers.country_id=country.country_id /* consider to use index */
WHERE
 first_name='Tariq' /* consider to use index */
AND
 last_name='Iqbal' /* consider to use index */

ตามคำค้นหาข้างต้น first_name คอลัมน์ last_name สามารถจัดทำดัชนีได้เนื่องจากอยู่ในส่วนคำสั่ง WHERE นอกจากนี้ยังสามารถพิจารณาเขตข้อมูลเพิ่มเติม country_id จากตารางประเทศเพื่อจัดทำดัชนีได้เนื่องจากอยู่ในส่วนคำสั่ง JOIN ดังนั้นการจัดทำดัชนีสามารถพิจารณาได้ในทุกฟิลด์ใน WHERE clause หรือ JOIN clause

รายการต่อไปนี้ยังมีเคล็ดลับบางประการที่คุณควรคำนึงถึงเสมอเมื่อต้องการสร้างดัชนีลงในตารางของคุณ:

  • จัดทำดัชนีเฉพาะคอลัมน์ที่จำเป็นในส่วนคำสั่ง WHERE และ ORDER BY การจัดทำดัชนีคอลัมน์จำนวนมากจะส่งผลเสียบ้าง
  • พยายามใช้ประโยชน์จากคุณลักษณะ "คำนำหน้าดัชนี" หรือ "ดัชนีหลายคอลัมน์" ของ MySQL หากคุณสร้างดัชนีเช่น INDEX (first_name, last_name) อย่าสร้าง INDEX (first_name) อย่างไรก็ตามไม่แนะนำให้ใช้ "คำนำหน้าดัชนี" หรือ "ดัชนีหลายคอลัมน์" ในทุกกรณีการค้นหา
  • ใช้แอตทริบิวต์ NOT NULL สำหรับคอลัมน์ที่คุณพิจารณาการสร้างดัชนีเพื่อที่จะไม่จัดเก็บค่า NULL
  • ใช้ตัวเลือก --log-long-format เพื่อบันทึกแบบสอบถามที่ไม่ได้ใช้ดัชนี ด้วยวิธีนี้คุณสามารถตรวจสอบไฟล์บันทึกนี้และปรับการสืบค้นของคุณให้เหมาะสม
  • คำสั่ง EXPLAIN ช่วยให้คุณเปิดเผยว่า MySQL จะดำเนินการค้นหาอย่างไร จะแสดงวิธีการและในตารางลำดับที่เข้าร่วม สิ่งนี้มีประโยชน์มากสำหรับการกำหนดวิธีการเขียนแบบสอบถามที่ปรับให้เหมาะสมและจำเป็นต้องจัดทำดัชนีคอลัมน์หรือไม่

ปรับปรุง (23 ก.พ. 58):

ดัชนีใด ๆ (ดี / ไม่ดี) เพิ่มเวลาแทรกและอัปเดต

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

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

การเลือกดัชนีควรฉลาด โปรดทราบว่าไม่ใช่ทุกคอลัมน์ที่ต้องการดัชนี


ขอบคุณสมนาถมันหมายความว่าดัชนีควรถูกสร้างขึ้นสำหรับคอลัมน์ที่เราวางแผนจะใช้WHEREเท่านั้นJOINSหรือHAVING?
Muhammad Babar

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

1
คำตอบจะได้รับประโยชน์จากการใส่ "คอลัมน์ที่อ้างถึงในส่วนคำสั่ง WHERE และคอลัมน์ที่ใช้ในส่วนคำสั่ง JOIN" ในส่วน TL; DR
jpmc26

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

@AjaxLeung: จำ maxim ของ Knuth "การเพิ่มประสิทธิภาพก่อนวัยเป็นรากเหง้าของความชั่วร้ายทั้งหมด" คุณสามารถสร้างดัชนีในคอลัมน์ไบนารีได้ แต่ควรขึ้นอยู่กับค่าใช้จ่าย (เช่นเวลาแทรกเวลาอัปเดต) หากตรรกะทางธุรกิจของคุณมักขึ้นอยู่กับสวิตช์ไบนารีนั้นคอลัมน์ไบนารีอาจจำเป็นต้องมีดัชนี
Somnath Muluk

20

บางคนตอบคำถามที่คล้ายกันที่นี่: คุณรู้ได้อย่างไรว่าดัชนีที่ดีคืออะไร?

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

พิจารณาประเภทของดัชนีที่คุณสร้างด้วยเช่นกัน - B-tree นั้นดีสำหรับสิ่งต่างๆส่วนใหญ่และอนุญาตให้มีการสืบค้นช่วง แต่ดัชนีแฮชจะช่วยให้คุณตรงประเด็น (แต่ไม่อนุญาตให้มีช่วง) ดัชนีประเภทอื่น ๆ มีข้อดีข้อเสียอื่น ๆ

โชคดี!


9

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

ดัชนีจะมีประโยชน์หาก:

  • คอลัมน์หรือคอลัมน์มีความเป็นเอกลักษณ์สูง
  • คุณมักจะต้องมองหาค่าที่แน่นอนหรือช่วงของค่าสำหรับคอลัมน์

สิ่งเหล่านี้จะไม่มีประโยชน์หาก:

  • คุณกำลังเลือก% ขนาดใหญ่ (> 10-20%) ของแถวในตาราง
  • การใช้พื้นที่เพิ่มเติมเป็นปัญหา
  • คุณต้องการเพิ่มประสิทธิภาพเม็ดมีดสูงสุด ทุกดัชนีบนตารางจะลดประสิทธิภาพการแทรกและการอัปเดตเนื่องจากต้องอัปเดตทุกครั้งที่ข้อมูลเปลี่ยนแปลง

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


การค้นหาสตริงที่ค่าสามารถอยู่ที่ใดก็ได้ภายในสตริงอาจทำให้ไม่ใช้ดัชนีเหล่านั้นในกรณีนั้น
Arthur Thomas

5

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

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

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

(ขออภัยหากฉันพูดซ้ำสิ่งที่กล่าวถึงในคำถามอื่นของคุณฉันไม่เคยเจอมาก่อน)


5

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

ซึ่งรวมถึง: คีย์ต่างประเทศ -

select * from tblOrder where status_id=:v_outstanding

ฟิลด์อธิบาย -

select * from tblCust where Surname like "O'Brian%"

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

select * from tblOrder where paidYN='N'

การพูดถึงคีย์ต่างประเทศอย่างชัดเจนของคุณทำให้ฉันคิดว่าจะเข้าร่วมอย่างชัดเจน
pfabri

3

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

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


3

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

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

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


นั่นไม่ถูกต้องทั้งหมดอย่างนั้น คุณสามารถสร้างดัชนีปกติที่ไม่ใช่คลัสเตอร์บนคอลัมน์ GUID ได้อย่างง่ายดาย - ทำไมล่ะ? GUID มีข้อเสียเปรียบมากหากคุณใช้เป็นคีย์การทำคลัสเตอร์ (เช่นสำหรับ CLUSTERED INDEX) ดังนั้นจึงเป็นสิ่งที่ควรใช้
marc_s

2

ชนิดข้อมูลตัวเลขที่เรียงลำดับจากน้อยไปมากหรือจากมากไปหาน้อยเป็นดัชนีที่ดีด้วยเหตุผลหลายประการ ประการแรกตัวเลขมักจะประเมินได้เร็วกว่าสตริง (varchar, char, nvarchar ฯลฯ ) ประการที่สองถ้าค่าของคุณไม่ได้เรียงลำดับแถวและ / หรือหน้าอาจต้องสับเพื่ออัปเดตดัชนีของคุณ นั่นคือค่าใช้จ่ายเพิ่มเติม

หากคุณใช้ SQL Server 2005 และตั้งค่าโดยใช้ตัวบ่งชี้ที่ไม่ซ้ำกัน (guids) และไม่จำเป็นต้องมีลักษณะสุ่มให้ตรวจสอบประเภทตัวบ่งชี้เฉพาะตามลำดับ

สุดท้ายนี้หากคุณกำลังพูดถึงดัชนีคลัสเตอร์คุณกำลังพูดถึงประเภทของข้อมูลทางกายภาพ หากคุณมีสตริงเป็นดัชนีคลัสเตอร์ของคุณนั่นอาจน่าเกลียด


1

หลักทั่วไปคือคอลัมน์ที่ใช้บ่อยมากในส่วนคำสั่ง WHERE ORDER BY และ GROUP BY หรือสิ่งใด ๆ ที่ดูเหมือนจะถูกใช้ในการรวมบ่อยๆ โปรดทราบว่าฉันหมายถึงดัชนีไม่ใช่คีย์หลัก

ไม่ได้ให้คำตอบ 'vanilla-ish' แต่ขึ้นอยู่กับวิธีการเข้าถึงข้อมูลของคุณ


1

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

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


0

ควรจะเร็วกว่านี้ถ้าคุณใช้ GUID สมมติว่าคุณมีบันทึก

  1. 100
  2. 200
  3. 3000
  4. ....

หากคุณมีดัชนี (การค้นหาแบบไบนารีคุณสามารถค้นหาตำแหน่งทางกายภาพของระเบียนที่คุณกำลังมองหาได้ในเวลา O (lg n) แทนที่จะค้นหาตามลำดับเวลา O (n) เนื่องจากคุณไม่รู้ว่าคุณมีระเบียนใด ในตารางของคุณ


0

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

ยกตัวอย่างฐานข้อมูลสมาชิกที่มีคีย์หลักของ Members Social Security Numnber เราเลือก SS เนื่องจากแอปพลิเคชัน Priamry อ้างอิงถึงบุคคลในลักษณะนี้ แต่คุณต้องการสร้างฟังก์ชันการค้นหาที่จะใช้ชื่อและนามสกุลของสมาชิกด้วย จากนั้นฉันขอแนะนำให้สร้างดัชนีในสองฟิลด์นั้น

ก่อนอื่นคุณควรค้นหาว่าคุณจะสืบค้นข้อมูลใดจากนั้นจึงทำการกำหนดว่าข้อมูลใดที่คุณต้องการจัดทำดัชนี

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