Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Các phương pháp hay nhất để sử dụng GUID làm khóa chính, cụ thể là về hiệu suất là gì?

GUID có vẻ là một lựa chọn tự nhiên cho khóa chính của bạn - và nếu bạn thực sự phải làm như vậy, bạn có thể tranh luận để sử dụng nó cho KHÓA CHÍNH của bảng. Điều tôi thực sự khuyên bạn nên không nên làm sử dụng cột GUID làm khóa phân nhóm , SQL Server thực hiện theo mặc định, trừ khi bạn yêu cầu cụ thể là không.

Bạn thực sự cần phải tách biệt hai vấn đề:

  1. khóa chính là một cấu trúc logic - một trong những khóa ứng cử viên xác định duy nhất và đáng tin cậy mọi hàng trong bảng của bạn. Đây có thể là bất cứ thứ gì, thực sự - một INT , một GUID , một chuỗi - chọn những gì có ý nghĩa nhất cho tình huống của bạn.

  2. khóa phân nhóm (cột hoặc các cột xác định "chỉ mục được phân nhóm" trên bảng) - đây là vật lý thứ liên quan đến lưu trữ và ở đây, loại dữ liệu nhỏ, ổn định, ngày càng tăng là lựa chọn tốt nhất của bạn - INT hoặc BIGINT làm tùy chọn mặc định của bạn.

Theo mặc định, khóa chính trên bảng SQL Server cũng được sử dụng làm khóa phân cụm - nhưng điều đó không cần phải như vậy! Cá nhân tôi đã thấy hiệu suất tăng đáng kể khi chia Khóa chính / cụm dựa trên GUID trước đó thành hai khóa riêng biệt - khóa chính (logic) trên GUID và khóa phân cụm (sắp xếp) trên một INT IDENTITY(1,1) cột.

Như Kimberly Tripp - Nữ hoàng lập chỉ mục - và những người khác đã nói rất nhiều lần - một GUID vì khóa phân cụm không tối ưu, vì do tính ngẫu nhiên của nó, nó sẽ dẫn đến phân mảnh trang và chỉ mục lớn và nói chung là hiệu suất kém.

Có, tôi biết - có newsequentialid() trong SQL Server 2005 trở lên - nhưng ngay cả điều đó cũng không thực sự và đầy đủ tuần tự và do đó cũng gặp phải các vấn đề tương tự như GUID - chỉ kém nổi bật hơn một chút.

Sau đó, có một vấn đề khác cần xem xét:khóa phân cụm trên bảng sẽ được thêm vào từng mục nhập trên mỗi và mọi chỉ mục không phân cụm trên bảng của bạn - vì vậy bạn thực sự muốn đảm bảo rằng nó càng nhỏ càng tốt. Thông thường, một INT với hơn 2 tỷ hàng sẽ là đủ cho phần lớn các bảng - và so với GUID là chìa khóa phân cụm, bạn có thể tiết kiệm cho mình hàng trăm MB dung lượng lưu trữ trên đĩa và trong bộ nhớ máy chủ.

Tính toán nhanh - sử dụng INT so với GUID làm Khóa chính và Khóa phân cụm:

  • Bảng cơ sở với 1'000'000 hàng (3,8 MB so với 15,26 MB)
  • 6 chỉ mục không phân biệt (22,89 MB so với 91,55 MB)

TỔNG CỘNG:25 MB so với 106 MB - và đó chỉ là trên một bàn duy nhất!

Một số thức ăn bổ sung cho sự suy nghĩ - những thứ tuyệt vời của Kimberly Tripp - hãy đọc nó, đọc nó một lần nữa, tiêu hóa nó! Đó thực sự là phúc âm lập chỉ mục của SQL Server.

  • HƯỚNG DẪN dưới dạng KHÓA CHÍNH và / hoặc khóa nhóm
  • Cuộc tranh luận về chỉ mục theo nhóm vẫn tiếp tục
  • Khóa phân nhóm ngày càng tăng - Cuộc tranh luận về chỉ mục được phân cụm .......... một lần nữa!
  • Dung lượng đĩa rẻ - điều đó không quan điểm!

Tái bút:tất nhiên, nếu bạn đang xử lý chỉ với vài trăm hoặc vài nghìn hàng - hầu hết các đối số này sẽ không thực sự có nhiều tác động đến bạn. Tuy nhiên:nếu bạn đi vào hàng chục hoặc hàng trăm nghìn hàng hoặc bạn bắt đầu đếm bằng hàng triệu - thì những điểm đó trở nên rất quan trọng và rất cần hiểu.

Cập nhật: nếu bạn muốn có PKGUID của mình cột làm khóa chính của bạn (nhưng không phải khóa phân cụm của bạn) và một cột khác MYINT (INT IDENTITY ) làm khóa phân cụm của bạn - sử dụng cái này:

CREATE TABLE dbo.MyTable
(PKGUID UNIQUEIDENTIFIER NOT NULL,
 MyINT INT IDENTITY(1,1) NOT NULL,
 .... add more columns as needed ...... )

ALTER TABLE dbo.MyTable
ADD CONSTRAINT PK_MyTable
PRIMARY KEY NONCLUSTERED (PKGUID)

CREATE UNIQUE CLUSTERED INDEX CIX_MyTable ON dbo.MyTable(MyINT)

Về cơ bản:bạn chỉ cần rõ ràng nói với PRIMARY KEY ràng buộc rằng nó NONCLUSTERED (nếu không, nó được tạo làm chỉ mục nhóm của bạn, theo mặc định) - và sau đó bạn tạo chỉ mục thứ hai được định nghĩa là CLUSTERED

Điều này sẽ hoạt động - và đó là một tùy chọn hợp lệ nếu bạn có một hệ thống hiện có cần được "thiết kế lại" để đạt hiệu suất. Đối với một hệ thống mới, nếu bạn bắt đầu từ đầu và bạn không ở trong trường hợp nhân bản, thì tôi luôn chọn ID INT IDENTITY(1,1) làm khóa chính được phân nhóm của tôi - hiệu quả hơn nhiều so với bất kỳ thứ gì khác!



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. pyodbc.connect () hoạt động nhưng không hoạt động với sqlalchemy.create_engine (). connect ()

  2. Tìm số nhỏ nhất không sử dụng trong SQL Server

  3. các lựa chọn thay thế để THAY THẾ trên kiểu dữ liệu văn bản hoặc ntext

  4. SQL - Trừ một giá trị cạn kiệt khỏi các hàng

  5. Làm cách nào để kết nối với cơ sở dữ liệu MSSQL bằng mô-đun DBI của Perl trong Windows?