Các cân nhắc về hiệu suất giữa việc sử dụng PK rộng so với khóa tổng hợp và UQ riêng biệt là gì?


10

Tôi có một số bảng trong đó các bản ghi có thể được xác định duy nhất với một số lĩnh vực kinh doanh rộng. Trước đây, tôi đã sử dụng các lĩnh vực này như một PK, với những lợi ích sau:

  • Sự đơn giản; không có trường ngoài và chỉ có một chỉ mục
  • Phân cụm cho phép kết hợp nhanh và các bộ lọc dựa trên phạm vi

Tuy nhiên, tôi đã nghe một trường hợp được thực hiện để tạo IDENTITY INTPK tổng hợp và thay vào đó thực thi khóa doanh nghiệp với một UNIQUEràng buộc riêng . Ưu điểm là PK hẹp tạo ra các chỉ số phụ nhỏ hơn nhiều.

Nếu một bảng không chỉ số khác hơn là PK, tôi không thấy lý do nào để ủng hộ cách tiếp cận thứ hai, mặc dù trong một bảng lớn nó có thể là tốt nhất khi cho rằng chỉ số có thể cần thiết trong tương lai, và do đó ủng hộ các tổng hợp PK hẹp . Tôi có thiếu bất kỳ cân nhắc nào không?

Ngẫu nhiên, tôi không tranh cãi về việc sử dụng các khóa tổng hợp trong kho dữ liệu, tôi chỉ quan tâm đến việc khi nào nên sử dụng một PK rộng duy nhất và khi nào nên sử dụng một PK hẹp cộng với một Vương quốc Anh rộng lớn.


1
bạn có thể thấy điều này hoặc điều này hữu ích trong số các câu hỏi khác trên trang web
Jack nói hãy thử topanswers.xyz

Câu trả lời:


11

Không có bất lợi đáng kể khi sử dụng khóa tự nhiên làm chỉ mục được nhóm

  • không có chỉ mục không phân cụm
  • không có khóa ngoại tham chiếu bảng này (nó là hàng cha mẹ)

Nhược điểm sẽ là tăng phân chia trang vì chèn dữ liệu sẽ được phân phối trên toàn bộ dữ liệu, thay vì ở cuối.

Trường hợp bạn có chỉ số FK hoặc NC, việc sử dụng chỉ số cụm hẹp, số, tăng có lợi thế. Bạn chỉ lặp lại một vài byte dữ liệu cho mỗi mục nhập NC hoặc FK, không phải là khóa kinh doanh / khóa tự nhiên.

Về lý do, hãy đọc quá 5 bài viết từ Google

Lưu ý tôi tránh sử dụng "khóa chính".

Bạn có thể có chỉ mục được nhóm trên khóa thay thế nhưng giữ PK theo quy tắc kinh doanh nhưng không được phân cụm. Chỉ cần đảm bảo rằng cụm là duy nhất bởi vì SQL sẽ thêm một "uniquifier" để làm cho nó trở nên như vậy.

Cuối cùng, có thể có một khóa thay thế nhưng không mù quáng trên mỗi bảng : nhiều bảng không cần một hoặc một khóa tổng hợp từ các bảng cha sẽ đủ


+1 cho tài liệu tham khảo bà Tripp xuất sắc trong việc lập chỉ mục.
Fabricio Araujo

2
+1 cho điểm hiệu năng không liên quan gì đến các khóa chính và mọi thứ phải làm với các chỉ mục.
nvogel

4

Mặc dù tôi có nguy cơ nêu rõ ràng, một chỉ mục trên khóa thay thế (số id) rất hữu ích nếu bạn cần xác định vị trí mọi thứ theo số id của chúng. Người dùng sẽ không đối phó với số id; họ sẽ đối phó với văn bản có thể đọc được. Vì vậy, bạn phải chuyển xung quanh văn bản và số id của nó rất nhiều, để giao diện người dùng có thể hiển thị văn bản và hoạt động trên số id.

Các dbms sẽ sử dụng loại chỉ mục đó để hỗ trợ các khóa ngoại, nếu bạn định nghĩa chúng theo cách đó.

Đôi khi bạn có thể cải thiện hiệu suất bằng cách sử dụng số id làm khóa ngoại, nhưng đó không phải là một cải tiến tuyệt đối. Trên hệ thống OLTP của chúng tôi, các khóa ngoại sử dụng khóa tự nhiên vượt trội so với khóa ngoại sử dụng số id trên bộ kiểm tra gồm khoảng 130 (tôi nghĩ) các truy vấn đại diện. (Bởi vì thông tin quan trọng thường được thực hiện trong các phím, sử dụng các phím tự nhiên tránh một nhiều của tham gia.) Việc tăng tốc trung bình là một yếu tố của 85 (tham gia sử dụng số id mất 85 lần thời gian để trả lại hàng).

Các thử nghiệm cho thấy rằng việc tham gia vào số id sẽ không thực hiện nhanh hơn đọc trên các khóa tự nhiên trong cơ sở dữ liệu của chúng tôi cho đến khi các bảng nhất định đạt được hàng triệu hàng. Độ rộng của hàng có liên quan nhiều đến điều đó - các hàng rộng hơn có nghĩa là ít hàng hơn vừa với một trang, do đó bạn phải đọc nhiều trang hơn để có được các hàng. Hầu như tất cả các bảng của chúng tôi đều ở mức 5NF; hầu hết các bảng khá hẹp.

Vào thời điểm các phép nối bắt đầu thực hiện các thao tác đọc đơn giản tại đây , việc đặt các bảng và chỉ mục quan trọng trên một đĩa trạng thái rắn có thể cấp hiệu suất cho hàng trăm triệu hàng.


3

Tôi có toàn bộ cơ sở dữ liệu oltp được thiết kế bằng các cột định danh để phân cụm + pk. Nó hoạt động khá nhanh khi chèn / tìm kiếm nhưng tôi đã thấy một vài vấn đề:
1. tùy chọn điền vào chỉ mục là vô ích vì việc chèn chỉ xảy ra ở cuối chỉ mục
2. nhiều không gian lưu trữ hơn. Tôi có các bảng với hàng chục triệu bản ghi và 1 int chiếm không gian. Mỗi bảng có một cột nhận dạng cho pk của nó phải có một chỉ mục khác để tìm kiếm doanh nghiệp, do đó cần nhiều dung lượng hơn.
3. khả năng mở rộng. Đây là vấn đề tồi tệ nhất. Bởi vì mỗi lần chèn đi đến cuối chỉ mục, mỗi lần chèn sẽ chỉ nhấn mạnh vào cuối chỉ mục (cấp phát, io cho ghi, v.v.). Bằng cách sử dụng khóa doanh nghiệp làm khóa phân cụm, bạn có thể phân phối các phần chèn đều trên chỉ mục. Điều đó có nghĩa là bạn vừa loại bỏ một điểm nóng lớn. Bạn có thể dễ dàng sử dụng nhiều tệp hơn cho một chỉ mục, mỗi tệp trên một ổ đĩa riêng, mỗi ổ đĩa hoạt động riêng.

Tôi bắt đầu thay đổi các bảng của mình từ một cột nhận dạng thành các khóa tự nhiên (có thể tách riêng để phân cụm & pk). Nó chỉ cảm thấy tốt hơn bây giờ.

Tôi sẽ đề xuất những điều sau đây (ít nhất là cho một oltp db):
1. sử dụng như một khóa phân cụm các cột bên phải theo đúng thứ tự để tối ưu hóa các truy vấn thường xuyên nhất
2. sử dụng pk các cột bên phải có ý nghĩa cho bảng của bạn

Nếu khóa cụm không đơn giản và chứa ký tự (char [], varchar, nvarchar), tôi nghĩ câu trả lời là 'nó phụ thuộc', bạn nên phân tích riêng từng trường hợp.

Tôi giữ nguyên tắc sau: tối ưu hóa cho truy vấn phổ biến nhất trong khi giảm thiểu trường hợp xấu nhất.

Tôi gần như quên một ví dụ. Tôi có một số bảng tham khảo chính họ. Nếu bảng đó có một cột nhận dạng cho khóa chính, thì việc chèn một hàng có thể yêu cầu cập nhật và việc chèn nhiều hơn một hàng tại một thời điểm có thể khó khăn nếu không thể (điều này phụ thuộc vào thiết kế bảng).


4
Khái niệm "điểm nóng" của bạn là một huyền thoại: dba.stackexchange.com/questions/1584/NH Và khi bạn nói "Bây giờ nó chỉ cảm thấy tốt hơn." bạn đã điểm chuẩn?
gbn

4
Đúng, ghi được thực hiện trong bộ nhớ không trực tiếp vào đĩa. Nếu bạn viết 20 hàng mới vào một trang, chỉ có 1 ghi vật lý vào tệp dữ liệu khi điểm kiểm tra xảy ra.
mrdenny

@mrdenny với đủ chèn ghi tất cả mọi thứ vào cuối chỉ mục sẽ gửi tất cả yêu cầu viết io vào cùng một tệp. Tôi nghi ngờ rằng việc sử dụng các giao dịch oltp bình thường, kịch bản này sẽ khó tái tạo, nhưng sử dụng một số tình huống đặc biệt như hồ sơ chèn hàng loạt / hàng loạt, sử dụng ssis để di chuyển một số dữ liệu kinh doanh sẽ đưa bạn đến đó.
Catalin Adler

1
@ user973156 có tất cả các yêu cầu sẽ làm với cùng một tệp, nhưng việc ghi không thực sự đi vào đĩa cho đến khi điểm kiểm tra chỉ xảy ra mỗi phút (theo mặc định) hoặc khi bộ đệm ghi đã đầy 50%. Việc bạn viết dữ liệu theo quy tắc này vẫn không thành vấn đề.
mrdenny

2
@ user973156 Sử dụng khóa phân cụm ngẫu nhiên SILL gây ra sự phân mảnh chỉ mục. Chỉ số phân mảnh SILL gây ra vấn đề hiệu suất. Và bảng của bạn sẽ đủ lớn để thực hiện phân mảnh chỉ mục sẽ mất một "thời gian dài" và ăn hết không gian nhật ký và không gian tempDB tiềm năng. Khi tôi có những người như Kimberly Tripp nói với tôi rằng đó là một ý tưởng hay, tôi lắng nghe. ( sqlskills.com/BLOGS/KIMBERLY/post/
Matt M

2

Từ quan điểm hiệu suất, việc lựa chọn khóa nào là khóa "chính" không tạo ra sự khác biệt nào cả. Không có sự khác biệt giữa việc sử dụng KHÓA CHÍNH và ràng buộc KHÔNG GIỚI HẠN để thực thi các khóa của bạn.

Hiệu suất được xác định bởi lựa chọn và loại chỉ mục và các tùy chọn lưu trữ khác và bằng cách các khóa được sử dụng trong các truy vấn và mã.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.