2009-02-02 14 views
9

SQLServer 2000 में पेजिंग क्वेरी करने का सबसे प्रभावी तरीका क्या होगा?SQLServer 2000 में कुशल पेजिंग (सीमा) क्वेरी?

जहां "पेजिंग क्वेरी" MySQL में LIMIT कथन का उपयोग करने के बराबर होगा।

संपादित करें: क्या संग्रहीत प्रक्रिया उस मामले में किसी भी सेट आधारित क्वेरी से अधिक कुशल हो सकती है?

उत्तर

11

Paging of Large Resultsets और विजेता रोकाउंट का उपयोग कर रहा है। इसके अलावा अधिक जटिल प्रश्नों के लिए एक सामान्य संस्करण भी है। लेकिन Jasmin Muharemovic :)

DECLARE @Sort /* the type of the sorting column */ 
SET ROWCOUNT @StartRow 
SELECT @Sort = SortColumn FROM Table ORDER BY SortColumn 
SET ROWCOUNT @PageSize 
SELECT ... FROM Table WHERE SortColumn >= @Sort ORDER BY SortColumn 

लेख पूरी स्रोत कोड शामिल हैं को श्रेय दें।

कृपया "2004-05-05 अपडेट करें" जानकारी पढ़ें। !

+3

में असमर्थित हैं यह मानता है कि वैल क्रमबद्ध कॉलम में ues अद्वितीय हैं। यदि आपके पास डेटा है जो आपके सॉर्ट कॉलम में दोहराता है, तो यह क्वेरी सही तरीके से निष्पादित नहीं हो सकती है। मान लीजिए कि आपकी क्वेरी वेतन के माध्यम से पेजिंग कर रही है और आपके पास 35 लोग हैं जो $ 40K कमाते हैं, 40 जो $ 50K और 20 $ 60K कमाते हैं। यदि आप 20 के पेज आकार के साथ इस समाधान का उपयोग करते हैं, तो आपका दूसरा "पृष्ठ" यहां पंक्ति 36 से शुरू होगा, उम्मीद के अनुसार 21 नहीं। – OneCleverMonkey

6

मुझे लगता है कि एक नेस्टेड SELECT TOP n क्वेरी शायद इसे पूरा करने का सबसे प्रभावी तरीका है।

SELECT TOP ThisPageRecordCount * 
FROM Table 
WHERE ID NOT IN (SELECT TOP BeforeThisPageRecordCount ID FROM Table ORDER BY OrderingColumn) 
ORDER BY OrderingColumn 

प्रति पृष्ठ वस्तुओं और (PageNumber - 1) * items-per-page साथ BeforeThisPageRecordCount साथ ThisPageRecordCount बदलें।

बेशक SQL सर्वर 2005 में बेहतर तरीका एक सीटीई में ROW_NUMBER() फ़ंक्शन का उपयोग करना है।

+0

बीटीडब्ल्यू, आपको * 2000 में गतिशील एसक्यूएल का उपयोग करने की आवश्यकता है, चर और खंड 0 शीर्ष 'खंड –

1

क्वेरी की दक्षता वास्तव में इस बात पर निर्भर करती है कि अंतर्निहित तालिका कैसे संरचित की जाती है।

चयन टॉप: हैं, कहते हैं कि तुम आईडी नामक एक प्राथमिक कुंजी है जो एक पहचान, और यह संकुल अनुक्रमणिका, और आप मान सकते हैं कि कोई भी उस पर IDENTITY_INSERTs कर रहा है है है, तो आप की तरह एक प्रश्न कर सकते हैं टेबल से XXX कहां आईडी> @LastPagesID;

इससे आपको जितनी जल्दी हो सके परिणाम मिलेंगे। बाकी सब कुछ जो वास्तव में कुशल होने वाला है, इस पर कुछ भिन्नता है - शायद यह एक आईडी नहीं है - हो सकता है कि आप पृष्ठ पर जो भी उपयोग कर रहे हैं वह वास्तव में एक तारीख है जिसे आप अद्वितीय मानते हैं, लेकिन आपको बिंदु मिल जाता है ... यहां दिखाए गए IN() आधारित प्रश्न शायद काम करेंगे, लेकिन वे आंशिक क्लस्टर या कवर इंडेक्स स्कैन के प्रदर्शन को स्पर्श नहीं करेंगे।

0

मुझे लगता है कि आप वास्तव में क्या यहाँ एसक्यूएल 2005

को उन्नत करने के लिए एसक्यूएल 2005 में एक बाध्यकारी कारण यह जल्दी और आसानी से साथ किया जा सकता है:

select ROW_NUMBER() over (order by [MyField]) as rowNum, * 
from [MyTable] 
where rowNum between @firstRow and @lastRow 

तुम सच में समस्या आ रही है एसक्यूएल 2000 के साथ मुझे चिंता होगी - माइक्रोसॉफ्ट अब पूरी तरह से इसका समर्थन नहीं कर रहा है क्योंकि अब यह दो पीढ़ी पहले है।

ऐसा करने का एक सबसे अच्छा तरीका नहीं है मुझे डर है - सभी समाधान थोड़े हैंक हैं।

@Petar पेत्रोव का जवाब शायद, सबसे सुसंगत तथापि है:

  • आप अपनी तरह के लिए एक छोटे मेज पर एक संकुल अनुक्रमणिका तो एएससी-DESC विधि (गतिशील दो प्रकार के प्रत्येक के निर्माण के साथ काम कर रहे हैं टॉप का उपयोग करने का तरीका) शायद तेज है।
  • यदि आपका डेटा अपेक्षाकृत स्थिर है और आपका सॉर्ट ठीक हो गया है तो आप अपनी खुद की पंक्ति संख्या फ़ील्ड जोड़ सकते हैं जिसे आप सॉर्ट ऑर्डर बदलते समय अपडेट करते हैं (भयानक लगता है लेकिन बड़ी टेबल के लिए तेज़ होगा)।

मुझे लगता है कि आप हर बार क्वेरी विश्लेषक के साथ tweaking कुछ घंटे देख रहे हैं। एक संग्रहित प्रो किसी भी तरह से कोई फर्क नहीं पड़ेगा - क्वेरी प्लान की कैशिंग बाधा होने की संभावना नहीं है।

0

यह एक सामान्य SQL Server 2000 संग्रहित प्रक्रिया है जो किसी भी तालिका पर पृष्ठांकन निष्पादित करेगी। संग्रहित प्रक्रिया तालिका के नाम को स्वीकार करती है, कॉलम आउटपुट (तालिका में सभी कॉलम के लिए डिफ़ॉल्ट), एक वैकल्पिक WHERE स्थिति, वैकल्पिक सॉर्ट ऑर्डर, पुनर्प्राप्त करने के लिए पृष्ठ संख्या और प्रति पृष्ठ पंक्तियों की संख्या स्वीकार करता है।

CREATE PROCEDURE [dbo].[GetPage] 
    @pTableName VARCHAR(30), 
    @pColumns VARCHAR(200) = '*', 
    @pFilter VARCHAR(200) = '', 
    @pSort VARCHAR(200) = '', 
    @pPage INT = 1, 
    @pPageRows INT = 10 
    AS 

    SET NOCOUNT ON 
    DECLARE @vSQL VARCHAR(4000) 
    DECLARE @vTempTable VARCHAR(30) 
    DECLARE @vRowStart INT 
    DECLARE @vTotalRows INT 

    SET @vTempTable = '##Tmp' + CAST(DATEPART(YYYY, GETDATE()) AS VARCHAR(4)) + 
    CAST(DATEPART(MM, GETDATE()) AS VARCHAR(2)) + 
    CAST(DATEPART(DD, GETDATE()) AS VARCHAR(2)) + 
    CAST(DATEPART(HH, GETDATE()) AS VARCHAR(2)) + 
    CAST(DATEPART(MI, GETDATE()) AS VARCHAR(2)) + 
    CAST(DATEPART(SS, GETDATE()) AS VARCHAR(2)) + 
    CAST(DATEPART(MS, GETDATE()) AS VARCHAR(3)) 

    SET @vSQL = 'SELECT ' + @pColumns + ', IDENTITY(INT, 1, 1) AS ROWID INTO ' + @vTempTable + ' FROM ' + @pTableName 

    IF @pFilter != '' AND @pFilter IS NOT NULL 
    SET @vSQL = @vSQL + ' WHERE ' + @pFilter 

    IF @pSort != '' AND @pSort IS NOT NULL 
    SET @vSQL = @vSQL + ' ORDER BY ' + @pSort 

    EXECUTE (@vSQL) 

    -- Get the total number of rows selected 
    SET @vTotalRows = @@ROWCOUNT 

    -- If page number = 0, set it to the first page 
    IF @pPage = 0 
    SET @pPage = 1 

    -- If page number is beyond the last page, set page to the last page 
    IF (@pPage * @pPageRows) > @vTotalRows 
    BEGIN 
    SET @pPage = @vTotalRows/@pPageRows 
    IF (@vTotalRows % @pPageRows) != 0 
    SET @pPage = @pPage + 1 
    END 

    SET @vRowStart = ((@pPage - 1) * @pPageRows) + 1 
    SET @vSQL = 'SELECT * FROM ' + @vTempTable + ' WHERE ROWID BETWEEN ' + CAST(@vRowStart AS VARCHAR(10)) + 
    ' AND ' + CAST((@vRowStart + @pPageRows - 1) AS VARCHAR(10)) + ' ORDER BY ROWID' 
    EXECUTE (@vSQL) 

    SET @vSQL = 'DROP TABLE ' + @vTempTable 
    EXECUTE (@vSQL) 

GO 

यहाँ कैसे Northwing डेटाबेस का उपयोग कर इसका इस्तेमाल करने पर कुछ उदाहरण है:

EXECUTE [dbo].[GetPage] 'Customers', '*', '', '', 1, 10 
EXECUTE [dbo].[GetPage] 'Customers', '*', '', 'CustomerID DESC', 1, 10 

पुष्टि करने के लिए, यह मेरा काम नहीं है, लेकिन के सौजन्य से है http://www.eggheadcafe.com/PrintSearchContent.asp?LINKID=1055

चीयर्स, जॉन

संबंधित मुद्दे