Foreign Key ปรับปรุงประสิทธิภาพการค้นหาหรือไม่


149

สมมติว่าฉันมี 2 ตารางผลิตภัณฑ์และหมวดหมู่สินค้า ทั้งสองตารางมีความสัมพันธ์กับ CategoryId และนี่คือแบบสอบถาม

SELECT p.ProductId, p.Name, c.CategoryId, c.Name AS Category
FROM Products p
INNER JOIN ProductCategories c ON p.CategoryId = c.CategoryId
WHERE c.CategoryId = 1;

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

ดังนั้นฉันต้องสร้างดัชนีบน Products.CategoryId เมื่อฉันสร้างแผนการดำเนินการอีกครั้งทั้งสองตารางทำการค้นหาดัชนี และค่าใช้จ่ายทรีย่อยโดยประมาณจะลดลงมาก

คำถามของฉันคือ:

  1. นอกจาก FK จะช่วยจำกัดความสัมพันธ์แล้วยังมีประโยชน์อื่นอีกไหม? ปรับปรุงประสิทธิภาพการสืบค้นหรือไม่

  2. ฉันควรสร้างดัชนีในคอลัมน์ FK ทั้งหมด (ไลค์ผลิตภัณฑ์ Products.CategoryId) ในตารางทั้งหมดหรือไม่

คำตอบ:


186

Foreign Keys เป็นเครื่องมืออ้างอิงความสมบูรณ์ไม่ใช่เครื่องมือประสิทธิภาพ อย่างน้อยใน SQL Server การสร้าง FK จะไม่สร้างดัชนีที่เกี่ยวข้องและคุณควรสร้างดัชนีในฟิลด์ FK ทั้งหมดเพื่อปรับปรุงเวลาค้นหา


40
โมเดลที่ดี (โดยทั่วไป) ทำงานได้ดีขึ้น
Kenny Evitt

10
"Foreign Keys เป็นเครื่องมือความสมบูรณ์ของความสัมพันธ์" - โปรดใช้คำว่า 'relational' ด้วยความระมัดระวัง Foreign Keys เป็นแนวคิดเกี่ยวกับฐานข้อมูลซึ่งย่อมาจากข้อ จำกัด ของ Referential Integrity พวกเขาไม่ได้เป็นส่วนหนึ่งของแบบจำลองเชิงสัมพันธ์ ฉันคิดว่าคุณพิมพ์ผิด
oneday เมื่อ

7
@ เคนนี่มักจะใช่ แต่บางครั้งแบบจำลองที่ดีกว่าก็มีค่าใช้จ่ายมากกว่า ตรงจุด: คีย์ต่างประเทศทำให้เกิดการประมวลผลมากขึ้นไม่น้อย
ฮันส์

8
foreign key จะปรับปรุงประสิทธิภาพอย่างน้อยใน MySQL นอกจากนี้คุณพูดถูกการสร้าง FK ไม่ได้สร้างดัชนี การสร้าง FK ต้องการดัชนี
Félix Gagnon-Grenier

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

58

Foreign Keys สามารถปรับปรุง (และเจ็บ) ประสิทธิภาพได้

  1. ตามที่ระบุไว้ที่นี่: กุญแจต่างประเทศช่วยเพิ่มประสิทธิภาพ

  2. คุณควรสร้างดัชนีในคอลัมน์ FK เสมอเพื่อลดการค้นหา SQL Server ไม่ทำสิ่งนี้โดยอัตโนมัติ

แก้ไข

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

คีย์ต่างประเทศสามารถปรับปรุงประสิทธิภาพได้

ข้อ จำกัด ของ Foreign Key จะช่วยเพิ่มประสิทธิภาพในเวลาที่อ่านข้อมูล แต่ในเวลาเดียวกันมันจะทำให้ประสิทธิภาพช้าลงเมื่อทำการแทรก / แก้ไข / ลบข้อมูล

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


3
นี่คือลิงก์ที่ให้รายละเอียดเกี่ยวกับวิธีที่พวกเขาสามารถลดประสิทธิภาพdevx.com/getHelpOn/10MinuteSolution/16595/0/page/2
cmsjr

3
มันสมเหตุสมผล แต่คุณจะพบกับสิ่งนี้ด้วยคำสั่งลบขนาดใหญ่ อาจสรุปได้ว่าในสภาพแวดล้อม OLAP FK ที่ไม่มีการจัดทำดัชนีจะปรับปรุงประสิทธิภาพในขณะที่ในสภาพแวดล้อม OLTP มันจะทำให้ประสิทธิภาพลดลง
Lieven Keersmaekers

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

1
@ChrisMoschini - ฉันไม่ได้สังเกตเห็นความคิดเห็นของคุณจนกระทั่งตอนนี้ ตามที่คุณพูดถึงลิงก์นั้นตายไปแล้ว แต่ส่วนหนึ่งของมันถูกกล่าวถึงในลิงค์ใหม่ (พร้อมรายละเอียด) ที่ฉันโพสต์ไว้
Lieven Keersmaekers

2
ลิงก์ของ Wayback Machine สำหรับการชนะ! บทความนี้ยังสามารถพบได้บน SQLMag.com, ที่นี่
John Eisbrener

15

foreign key คือแนวคิด DBMS สำหรับการตรวจสอบความถูกต้องของฐานข้อมูล

ผลกระทบด้านประสิทธิภาพ / การปรับปรุงใด ๆ จะเฉพาะเจาะจงกับเทคโนโลยีฐานข้อมูลที่ใช้และเป็นรองตามวัตถุประสงค์ของ foreign key

เป็นแนวปฏิบัติที่ดีใน SQL Server เพื่อให้มั่นใจว่ากุญแจต่างประเทศทั้งหมดมีดัชนีที่ไม่ได้ทำคลัสเตอร์อย่างน้อย

ฉันหวังว่าสิ่งนี้จะช่วยคุณได้ แต่โปรดอย่าลังเลที่จะขอรายละเอียดเพิ่มเติม


9
@Kenny Evitt หากคุณไม่มีความสมบูรณ์ข้อมูลของคุณก็ไร้ประโยชน์ ฉันพบว่าขายง่ายมาก
HLGEM

@HLGEM ได้รับข้อผิดพลาด 404ครั้งในขณะที่ยังคงสามารถรับได้ค่อนข้าง การได้รับผลตอบแทนที่ดีเยี่ยมโดยใช้ทรัพยากรที่ถูกกว่าและระบบที่ซับซ้อนน้อยลง คุณอาจจะสนใจในทฤษฎีบท CAP
Daniel Dinnyes

8
@Daniel Dinnyes ความถูกต้องของข้อมูลไม่ได้เกี่ยวกับการรับข้อผิดพลาด 404 มันเกี่ยวกับการมีข้อมูลที่ใช้งานได้ มันเกี่ยวกับการไม่สูญเสียคำสั่งซื้อและข้อมูลทางการเงินสำหรับรายงานเช่นเนื่องจากความสามารถของนักพัฒนา ไม่มีข้อยกเว้นสำหรับการไม่ใช้คีย์ต่างประเทศ
HLGEM

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

1
"Foreign Keys เป็นเครื่องมือความสมบูรณ์ของความสัมพันธ์" - โปรดใช้คำว่า 'relational' ด้วยความระมัดระวัง Foreign Keys เป็นแนวคิดเกี่ยวกับฐานข้อมูลซึ่งย่อมาจากข้อ จำกัด ของ Referential Integrity พวกเขาไม่ได้เป็นส่วนหนึ่งของแบบจำลองเชิงสัมพันธ์ ฉันคิดว่าคุณพิมพ์ผิด
oneday เมื่อ

4

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


3

คุณสามารถใช้มันเพื่อช่วยให้แบบสอบถามมีประสิทธิภาพมากขึ้น มันช่วยให้คุณสามารถปรับโครงสร้างแบบสอบถามใน SQL Server เพื่อใช้การเข้าร่วมด้านนอกแทนที่จะเป็นภายในที่ลบ sql เซิร์ฟเวอร์ที่ไม่จำเป็นต้องตรวจสอบว่ามีเป็นโมฆะในคอลัมน์ คุณไม่จำเป็นต้องใส่ตัวระบุในนั้นเนื่องจากความสัมพันธ์ของคีย์ต่างประเทศนั้น inforces สำหรับคุณแล้ว

ดังนั้นนี่คือ:

    select p.ProductId, p.Name, c.CategoryId, c.Name AS Category 
from Products p inner join ProductCategories c on p.CategoryId = c.CategoryIdwhere c.CategoryId = 1;

กลายเป็นสิ่งนี้:

SELECT p.ProductId, p.Name, c.CategoryId, c.Name AS Category 
FROM ProductCategories c 
LEFT OUTER JOIN Products P ON
c.CategoryId = p.CategoryId 
WHERE c.CategoryId = 1;

สิ่งนี้ไม่จำเป็นต้องทำให้มีประสิทธิภาพมากในคิวรีขนาดเล็ก แต่เมื่อตารางมีขนาดใหญ่ก็จะมีประสิทธิภาพมากขึ้น


3
โดยทั่วไปแล้วการรวมภายนอกจะมีประสิทธิภาพน้อยกว่าการรวมภายใน ( stackoverflow.com/a/2726683/155892 ) ตอนนี้การสืบค้นของคุณกำลังทำให้เข้าใจผิด: คุณใช้ฐานข้อมูลเพื่อเปลี่ยนการรวมภายนอกของคุณเป็นการรวมภายใน (คืนค่าประสิทธิภาพ) แทนที่จะทำสิ่งนั้นอย่างชัดเจน
Mark Sowul

2

สำหรับ MySQL 5.7 มันสามารถเร่งความเร็วการสืบค้นที่เกี่ยวข้องกับการรวมหลายรายการได้อย่างน่าอัศจรรย์

ฉันใช้ 'อธิบาย' เพื่อทำความเข้าใจข้อความค้นหาของฉันและพบว่าฉันเข้าร่วม 4-5 ตาราง - โดยที่ไม่ต้องใช้คีย์เลย ฉันไม่ได้ทำอะไรนอกจากเพิ่มคีย์ต่างประเทศในตารางเหล่านี้และผลลัพธ์ก็ลดลง 90% ในการโหลด แบบสอบถามที่ใช้เวลา> 5s ใช้เวลา 500ms หรือน้อยกว่า

นั่นคือการปรับปรุงอย่างมาก!

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

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


ตารางมีดัชนีที่จำเป็นในการสร้างคีย์ต่างประเทศก่อนที่คุณจะเพิ่มหรือไม่
จอร์จ

1

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


0

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


0

คีย์ต่างประเทศของ SQL Server 2008 สามารถมีอิทธิพลต่อประสิทธิภาพการทำงานโดยการเลือกวิธีที่เอ็นจินฐานข้อมูลเลือกเพื่อปรับให้เหมาะสมกับคิวรี อ้างถึงสตาร์เข้าร่วมการวิเคราะห์พฤติกรรมในบทความต่อไปนี้: https://technet.microsoft.com/en-us/library/2008.04.dwperformance.aspx

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