इस क्‍वेरी में प्राथमिक (क्‍लस्‍टरेड) कुंजी का उपयोग क्‍यों नहीं किया जा रहा है?


10

मेरे पास SQL ​​Server 2008 R2 तालिका है जिसकी स्कीमा संरचना निम्नानुसार है:

CREATE TABLE [dbo].[CDSIM_BE]
(
    [ID] [bigint] NOT NULL,
    [EquipmentID] [varchar](50) NOT NULL,
    [SerialNumber] [varchar](50) NULL,
    [PyrID] [varchar](50) NULL,
    [MeasMode] [varchar](50) NULL,
    [ReadTime] [datetime] NOT NULL,
    [SubID] [varchar](15) NULL,
    [ProbePosition] [float] NULL,
    [DataPoint] [int] NULL,

    CONSTRAINT [PK_CDSIM_BE] 
    PRIMARY KEY CLUSTERED ([ID] ASC, [EquipmentID] ASC, [ReadTime] ASC)
         WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
               IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
               ALLOW_PAGE_LOCKS = ON) ON [MonthlyArchiveScheme9]([ReadTime])
) ON [MonthlyArchiveScheme9]([ReadTime])

CREATE NONCLUSTERED INDEX [idx_CDSIM_BE__SubID_ProbePosition] 
ON [dbo].[CDSIM_BE] ([SubID] ASC, [ProbePosition] ASC)
INCLUDE ([EquipmentID], [ReadTime], [BECorr]) 
    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
          SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, 
          ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [MonthlyArchiveScheme9]([ReadTime])

CREATE NONCLUSTERED INDEX [IX_CDSIM_BE_ProbePosition] 
ON [dbo].[CDSIM_BE] ([ProbePosition] ASC)
INCLUDE ([SerialNumber], [SubID]) 
    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
          SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, 
          ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [MonthlyArchiveScheme9]([ReadTime])

CREATE NONCLUSTERED INDEX [IX_CSDIM_Readtime] 
ON [dbo].[CDSIM_BE]([ReadTime] ASC)
INCLUDE ([EquipmentID]) 
    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
          SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, 
          ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [MonthlyArchiveScheme9]([ReadTime])

और मैं इस सरल क्वेरी को निष्पादित कर रहा हूं:

Select Max(Id)
From dbo.CDSIM_BE

तालिका में ~ 2.5B पंक्तियाँ हैं।

क्वेरी प्लान इंडेक्स पर एक इंडेक्स स्कैन दिखाता है IX_CdSIM_BE_ProbePosition। मैं सोच रहा था कि SQL सर्वर बस क्लस्टर (और प्राथमिक) इंडेक्स का उपयोग क्यों नहीं करेगा और तुरंत तालिका में अंतिम पंक्ति पर जाएं और आईडी मान प्राप्त करें, क्योंकि यह अधिकतम होना चाहिए।


इस संबंध में अधिकतम () और मिनट () समुच्चय अक्सर समस्याग्रस्त होते हैं। यदि आप यह सुनिश्चित करना चाहते हैं कि इसके बजाय एक इंडेक्स का उपयोग किया जाएselect top 1 Id from dbo.CDSIM_BE order by Id descending;
पीटर गेकर्न्स

4
क्लस्टर किए गए इंडेक्स का विभाजन किया जाता है, ReadTimeइसलिए यह पीके का उपयोग नहीं कर सकता जैसा कि आप वर्णन करते हैं। इसके Max(Id)लिए प्रत्येक विभाजन की खोज करनी होगी और फिर उनमें से अधिकतम को खोजना होगा। यह संभव है कि इस तरह की योजना को फिर से लिखना संभव है क्योंकि dba.stackexchange.com/a/99418/3690
मार्टिन स्मिथ

जवाबों:


7

क्लस्टर किए गए इंडेक्स का विभाजन किया जाता है, ReadTimeइसलिए यह पीके का उपयोग नहीं कर सकता जैसा कि आप वर्णन करते हैं। इसके Max(Id)लिए प्रत्येक विभाजन की खोज करनी होगी और फिर उनमें से अधिकतम को खोजना होगा। यह है क्वेरी के पुनर्लेखन के लिए लेकिन इस तरह की एक योजना पाने के लिए संभव।

लेख के आधार पर एक उदाहरण का उपयोग करके यहां एक संभावित पुनर्लेखन हो सकता है

SELECT MAX(ID) AS ID
FROM   sys.partitions AS P
       CROSS APPLY (SELECT MAX(ID) AS ID
                    FROM   [dbo].[CDSIM_BE]
                    WHERE  $PARTITION.MonthlyArchiveFunction9(ReadTime) 
                                                    = P.partition_number) AS A
WHERE  P.object_id = OBJECT_ID('dbo.CDSIM_BE')
       AND P.index_id <= 1; 

बदले में प्रत्येक विभाजन को संसाधित करने के लिए।

ध्यान दें कि योजना में अभी भी एक स्कैन है (विभाजन का चयन करने की तलाश के साथ) लेकिन यह विभाजन का पूर्ण स्कैन नहीं है।

स्कैन दिशा "बैकवर्ड" के साथ सूचकांक क्रम में है। TOPइटरेटर के बाद पहले एक प्राप्त होता है स्कैन से पंक्तियों का अनुरोध रोक सकता है।

यहाँ छवि विवरण दर्ज करें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.