Biz premature optimization moduna gitmek önce, aşağıdaki sorgu şablonu içine bakmak yararlı olabilir. Başka bir şey varsa, bu olası optimizasyonlar etkinliği ölçülebilir hangi karşı bir temel olarak kullanılabilir.
SELECT T.Tagid, TagInfo.TagName, COUNT(*)
FROM Items I
JOIN Tags TagInfo ON TagInfo.TagId = T.TagId
JOIN ItemTagMap T ON I.ItemId = T.ItemId
--JOIN ItemTagMap T1 ON I.ItemId = T1.ItemId
WHERE I.ItemId IN
(
SELECT ItemId
FROM Items
WHERE -- Some typical initial search criteria
Title LIKE 'Bug Report%' -- Or some fulltext filter instead...
AND ItemDate > '02/22/2008'
AND Status = 'C'
)
--AND T1.TagId = 'MySql'
GROUP BY T.TagId, TagInfo.TagName
ORDER BY COUNT(*) DESC
The subquery is the "driving query", i.e. the one corresponding to the end-user's initial criteria. (see below for details on how this query, required multiple times may fit in an overall optimized flow)
Commented is the JOIN on T1 (and possibly T2, T3, when several tags are selected), and, with the WHERE clause, the associated criteria. These are needed when the user selects a particular tag, whether as part of the initial search or by refinement. (It may be more efficient to place these joins and where clauses within the sub-query; more on these below)
Discussion...
The "driving query", or a variation thereof is needed for two distinct purposes:
- Ilişkili tüm etiketleri numaralandırmak için gerekli itemid ve complete listesini sağlamak için 1..
- 2. Öğe tabloda Ürün detay bilgi ararken amacıyla, ilk N ItemId değerleri (N ekran sayfa boyutu olarak) sağlamaktır.
İkinci liste alfabetik olarak artan, azalan Tarihe göre, kullanıcının seçimine (diyelim, ya da Başlığı göre sıralanır gereken sayede tam listesi, sıralanması için (ya da farklı bir düzende sıralama yararlanabilir) gerekmez unutmayın .) Ayrıca, gereken herhangi bir sıralama düzeni varsa, sorgunun maliyeti (SQL kendisi tarafından tek optimizasyon utangaç ve / veya bazı denormalizasyon tam listesi ile ilgili ima unutmayın, SQL o listede son kayıtları "görmek" gerekiyor , durumda onlar) sort-bilge, üst aittir.
Bu son gerçek, her iki amaç için aynı sorguyu sahip lehine, ilgili liste, geçici bir tabloda depolanan edilebilir. Genel akışı hızlı bir şekilde detayları ile üst N Öğe kayıtları arama ve bir kerede uygulama bu döner olacaktır. Uygulama daha sonra ajax-moda iyileştirmeler için Etiketler listesini elde edebilirsiniz. Bu liste subquery tarafından değiştirildiği yukarıda birini, akin bir sorgu ile üretmek olacaktır "temporaryTable seçin *." Oran, SQL optimizer (bazı durumlarda) bu listeyi sıralamak için karar olacağını iyi, en oldukça ikinci bunu tahmin ve açıkça sıralama daha, bunu vereyim.
Düşünün bir diğer nokta belki de "itici sorgu" iç ItemTagMap masanın üzerine (ler) katılmak getirmek yerine o kadar yukarıda gösterildiği gibi. Hem performans için, bunu yapmak için, muhtemelen en iyi ve # 2 amaç (öğelerin bir sayfa ekran) için doğru liste üretecektir çünkü.
Yukarıda açıklanan sorgu / akış olasılıkla bile nispeten mütevazı donanım üzerinde, oldukça iyi dönüşebilecek; geçici belki saniyede 10 kadar sürekli kullanıcı aramaları ile 1/2 Milyon + Öğeler, içine. En önemli faktörlerden biri ilk arama kriterlerinin seçicilik olacaktır.
Optimization ideas
- [Tipik bir arama durumlarda ve veri istatistikleri bağlı] bu (aslında çoğaltarak) ItemTagMap masaya Öğeler 'bazı alanları getirerek denormalize mantıklı olabilir. Özellikle kısa alanlar vardır 'welcome' olabilir.
- Veri milyon + Öğeler büyüdükçe, bazı etiketleri genellikle güçlü korelasyon yararlanılabilecek (ex: SO, PHP sık sık sebepsiz btw sık sık, MySQL ile birlikte geliyor ...), çeşitli hileler ile. Örneğin "multi-Tag" TagIds tanıtımı biraz daha karmaşık giriş mantığı render olabilir, ama aynı zamanda önemli ölçüde Harita boyutunu azaltabilir.
-- 'nough said! --
Appropriate architecture and optimizations should be selected in light of the actual requirements and of the effective data statistical profile...