मान लीजिए कि मेरे पास एक एकल तालिका है
CREATE TABLE Ticket (
TicketId int NOT NULL,
InsertDateTime datetime NOT NULL,
SiteId int NOT NULL,
StatusId tinyint NOT NULL,
AssignedId int NULL,
ReportedById int NOT NULL,
CategoryId int NULL
);
इस उदाहरण TicketId
में प्राथमिक कुंजी है।
मैं चाहता हूं कि उपयोगकर्ता इस तालिका के विरुद्ध "आंशिक रूप से तदर्थ" क्वेरी बनाने में सक्षम हों। मैं आंशिक रूप से कहता हूं क्योंकि क्वेरी के कुछ हिस्से हमेशा तय होंगे:
- क्वेरी हमेशा a पर एक श्रेणी फ़िल्टर
करेगी
InsertDateTime
- क्वेरी हमेशा रहेगी
ORDER BY InsertDateTime DESC
- क्वेरी पृष्ठ परिणाम देगा
उपयोगकर्ता वैकल्पिक रूप से किसी अन्य कॉलम पर फ़िल्टर कर सकता है। वे कोई नहीं, एक, या कई पर फ़िल्टर कर सकते हैं। और प्रत्येक स्तंभ के लिए उपयोगकर्ता मानों के एक सेट से चुन सकता है जिसे एक विघटन के रूप में लागू किया जाएगा। उदाहरण के लिए:
SELECT
TicketId
FROM (
SELECT
TicketId,
ROW_NUMBER() OVER(ORDER BY InsertDateTime DESC) as RowNum
FROM Ticket
WHERE InsertDateTime >= '2013-01-01' AND InsertDateTime < '2013-02-01'
AND StatusId IN (1,2,3)
AND (CategoryId IN (10,11) OR CategoryId IS NULL)
) _
WHERE RowNum BETWEEN 1 AND 100;
अब मान लें कि तालिका में 100,000,000 पंक्तियाँ हैं।
सबसे अच्छा मैं आ सकता है एक कवरिंग इंडेक्स जिसमें "वैकल्पिक" कॉलम में से प्रत्येक शामिल है:
CREATE NONCLUSTERED INDEX IX_Ticket_Covering ON Ticket (
InsertDateTime DESC
) INCLUDE (
SiteId, StatusId, AssignedId, ReportedById, CategoryId
);
यह मुझे एक क्वेरी प्लान इस प्रकार देता है:
- चुनते हैं
- फ़िल्टर
- ऊपर
- अनुक्रम परियोजना (गणना स्केलर)
- खंड
- सूचकांक की तलाश
- खंड
- अनुक्रम परियोजना (गणना स्केलर)
- ऊपर
- फ़िल्टर
यह बहुत अच्छा लगता है। लगभग 80% -90% लागत इंडेक्स सीक ऑपरेशन से आती है, जो आदर्श है।
क्या इस तरह की खोज को लागू करने के लिए बेहतर रणनीतियां हैं?
मैं जरूरी नहीं कि ग्राहक के लिए वैकल्पिक फ़िल्टरिंग को उतारना चाहता हूं क्योंकि कुछ मामलों में "निश्चित" भाग से सेट किया गया परिणाम 100 सेकंड या उससे अधिक हो सकता है। क्लाइंट तब सॉर्टिंग और पेजिंग के लिए भी जिम्मेदार होगा जो क्लाइंट के लिए बहुत काम कर सकता है।
RowNum BETWEEN 101 AND 200
?