Tôi đang xây dựng một ứng dụng web (hệ thống quản lý dự án) và tôi đã tự hỏi về điều này khi nói đến hiệu suất.
Tôi có một bảng Vấn đề và bên trong nó có 12 khóa ngoại liên kết với nhiều bảng khác. Trong số đó, 8 trong số đó tôi sẽ cần tham gia để lấy trường tiêu đề từ các bảng khác để bản ghi có ý nghĩa trong ứng dụng web nhưng sau đó có nghĩa là thực hiện 8 lần tham gia có vẻ thực sự quá mức đặc biệt là vì tôi chỉ tham gia 1 trường cho mỗi tham gia.
Bây giờ tôi cũng đã được yêu cầu sử dụng khóa chính tăng tự động (trừ khi shending là mối lo ngại trong trường hợp nào tôi nên sử dụng GUID) vì lý do lâu dài nhưng việc sử dụng varchar (max length 32) có tệ đến mức nào? Ý tôi là hầu hết các bảng này có thể sẽ không có nhiều hồ sơ (hầu hết trong số chúng phải dưới 20). Ngoài ra, nếu tôi sử dụng tiêu đề làm khóa chính, tôi sẽ không phải tham gia 95% thời gian vì vậy với 95% sql, tôi thậm chí sẽ xảy ra bất kỳ cú đánh hiệu suất nào (tôi nghĩ). Nhược điểm duy nhất tôi có thể nghĩ là tôi có là tôi sẽ sử dụng dung lượng ổ đĩa cao hơn (nhưng xuống một ngày thì đó thực sự là một vấn đề lớn).
Lý do tôi sử dụng bảng tra cứu cho rất nhiều thứ này thay vì enums là vì tôi cần tất cả các giá trị này để người dùng cuối có thể định cấu hình thông qua chính ứng dụng.
Nhược điểm của việc sử dụng varchar làm khóa chính cho bảng không ngoại trừ có nhiều bản ghi là gì?
CẬP NHẬT - Một số bài kiểm tra
Vì vậy, tôi quyết định làm một số thử nghiệm cơ bản về công cụ này. Tôi có 100000 hồ sơ và đây là các truy vấn cơ bản:
Truy vấn cơ sở VARCHAR FK
SELECT i.id, i.key, i.title, i.reporterUserUsername, i.assignedUserUsername, i.projectTitle,
i.ProjectComponentTitle, i.affectedProjectVersionTitle, i.originalFixedProjectVersionTitle,
i.fixedProjectVersionTitle, i.durationEstimate, i.storyPoints, i.dueDate,
i.issueSecurityLevelId, i.creatorUserUsername, i.createdTimestamp,
i.updatedTimestamp, i.issueTypeId, i.issueStatusId
FROM ProjectManagement.Issues i
Truy vấn cơ sở INT FK
SELECT i.id, i.key, i.title, ru.username as reporterUserUsername,
au.username as assignedUserUsername, p.title as projectTitle,
pc.title as ProjectComponentTitle, pva.title as affectedProjectVersionTitle,
pvo.title as originalFixedProjectVersionTitle, pvf.title as fixedProjectVersionTitle,
i.durationEstimate, i.storyPoints, i.dueDate, isl.title as issueSecurityLevelId,
cu.username as creatorUserUsername, i.createdTimestamp, i.updatedTimestamp,
it.title as issueTypeId, is.title as issueStatusId
FROM ProjectManagement2.Issues i
INNER JOIN ProjectManagement2.IssueTypes `it` ON it.id = i.issueTypeId
INNER JOIN ProjectManagement2.IssueStatuses `is` ON is.id = i.issueStatusId
INNER JOIN ProjectManagement2.Users `ru` ON ru.id = i.reporterUserId
INNER JOIN ProjectManagement2.Users `au` ON au.id = i.assignedUserId
INNER JOIN ProjectManagement2.Users `cu` ON cu.id = i.creatorUserId
INNER JOIN ProjectManagement2.Projects `p` ON p.id = i.projectId
INNER JOIN ProjectManagement2.`ProjectComponents` `pc` ON pc.id = i.projectComponentId
INNER JOIN ProjectManagement2.ProjectVersions `pva` ON pva.id = i.affectedProjectVersionId
INNER JOIN ProjectManagement2.ProjectVersions `pvo` ON pvo.id = i.originalFixedProjectVersionId
INNER JOIN ProjectManagement2.ProjectVersions `pvf` ON pvf.id = i.fixedProjectVersionId
INNER JOIN ProjectManagement2.IssueSecurityLevels isl ON isl.id = i.issueSecurityLevelId
Tôi cũng đã chạy các truy vấn này với các bổ sung sau:
- Chọn mục cụ thể (trong đó i.key = 43298)
- Nhóm bởi i.id
- Sắp xếp theo (it.title cho int FK, i.suTypeId cho varchar FK)
- Giới hạn (50000, 100)
- Nhóm và giới hạn cùng nhau
- Nhóm, thứ tự và giới hạn cùng nhau
Kết quả cho những điều này:
NHIỀU LOẠI: VARCHAR FK TIME / INT FK TIME
Truy vấn cơ sở: ~ 4ms / ~ 52ms
Chọn mục cụ thể: ~ 140ms / ~ 250ms
Nhóm theo i.id: ~ 4ms / ~ 2.8 giây
Đặt hàng theo: ~ 231ms / ~ 2 giây
Giới hạn: ~ 67ms / ~ 343ms
Nhóm và giới hạn cùng nhau: ~ 504ms / ~ 2 giây
Nhóm, thứ tự và giới hạn cùng nhau: ~ 504ms /~2.3 giây
Bây giờ tôi không biết cấu hình nào tôi có thể thực hiện để làm cho cái này hoặc cái kia (hoặc cả hai) nhanh hơn nhưng có vẻ như VARCHAR FK thấy nhanh hơn trong các truy vấn dữ liệu (đôi khi nhanh hơn rất nhiều).
Tôi đoán tôi phải lựa chọn liệu cải thiện tốc độ đó có xứng đáng với kích thước chỉ mục / dữ liệu bổ sung hay không.