Bir web uygulaması (proje yönetim sistemi) oluşturuyorum ve performans söz konusu olduğunda bunu merak ediyorum.
İçinde Sorunlar tablo var içinde çeşitli diğer tablolara bağlantı 12 yabancı anahtar vardır. bunlardan 8 tanesi, kayıtların bir web uygulamasında herhangi bir anlam ifade edebilmesi için diğer tablolardan başlık alanını almak için katılmam gerekir, ancak özellikle sadece çektiğim için gerçekten çok fazla görünen 8 birleştirme yapmak anlamına gelir. Bu birleştirmeler için 1 alan.
Şimdi de otomatik olarak artan birincil anahtar kullanmam söylendi (parçalama, bu durumda bir GUID kullanmalıyım bir endişe olmadığı sürece) kalıcılık nedenleriyle, ancak bir varchar (maksimum uzunluk 32) performansı akıllıca kullanmak ne kadar kötü? Demek istediğim, bu tabloların çoğu muhtemelen pek çok kayda sahip olmayacak (çoğu 20 yaşın altında olmalı). Ayrıca başlığı birincil anahtar olarak kullanırsam,% 95 oranında katılmam gerekmeyecek, bu yüzden sql'ın% 95'i için herhangi bir performans hitini bile oluşturacağım (sanırım). I-ebilmek düşün tek dezavantajı ben daha yüksek disk alanı kullanımı olacak (ama bir gün aşağı gerçekten büyük bir anlaşma).
Arama tabloları numaralandırma yerine bir sürü için kullanmamın nedeni, tüm bu değerleri uygulamanın kendisi aracılığıyla son kullanıcı tarafından yapılandırılabilir olması gerektiğidir.
Birçok kayda sahip olmayan bir tablonun birincil anahtarı olarak varchar kullanmanın dezavantajları nelerdir?
GÜNCELLEME - Bazı Testler
Ben de bu konuda bazı temel testler yapmaya karar verdim. 100000 kayıtları var ve bunlar temel sorgular:
Temel VARCHAR FK Sorgusu
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
Temel INT FK Sorgusu
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
Bu sorguyu aşağıdaki eklemelerle de çalıştırdım:
- Belirli bir öğe seçin (burada i.key = 43298)
- Grup i.id
- Sıralama: (int FK için it.title, varchar FK için i.issueTypeId)
- Sınır (50000, 100)
- Gruplama ve sınırlama
- Gruplama, sipariş verme ve sınırlama
Bunların sonuçları:
QUERY TYPE: VARCHAR FK TIME / INT FK TIME
Temel sorgu: ~ 4ms / ~ 52ms
Belirli bir öğe seçin: ~ 140ms / ~ 250ms
Grup i.id'ye göre: ~ 4ms / ~ 2.8sn
Sipariş: ~ 231ms / ~ 2sn
Sınır: ~ 67ms / ~ 343ms
Gruplandırın ve birlikte sınırlandırın: ~ 504ms / ~ 2sn
Gruplayın, sipariş verin ve birlikte sınırlandırın: ~ 504ms /~2.3sec
Şimdi birini veya diğerini (veya her ikisini) daha hızlı yapmak için hangi yapılandırmayı yapabileceğimi bilmiyorum ama VARCHAR FK veri sorgularında daha hızlı görüyor gibi görünüyor (bazen çok daha hızlı).
Sanırım bu hız gelişiminin ekstra veri / dizin boyutuna değip değmeyeceğini seçmek zorundayım.