दो तारीख स्तंभों के लिए खोज योग्य खंड


24

मेरे पास क्या है, मेरे लिए, SARGability पर एक दिलचस्प सवाल। इस स्थिति में, यह दो दिनांक स्तंभों के बीच अंतर पर एक विधेय का उपयोग करने के बारे में है। यहाँ सेटअप है:

USE [tempdb]
SET NOCOUNT ON  

IF OBJECT_ID('tempdb..#sargme') IS NOT NULL
BEGIN
DROP TABLE #sargme
END

SELECT TOP 1000
IDENTITY (BIGINT, 1,1) AS ID,
CAST(DATEADD(DAY, [m].[severity] * -1, GETDATE()) AS DATE) AS [DateCol1],
CAST(DATEADD(DAY, [m].[severity], GETDATE()) AS DATE) AS [DateCol2]
INTO #sargme
FROM sys.[messages] AS [m]

ALTER TABLE [#sargme] ADD CONSTRAINT [pk_whatever] PRIMARY KEY CLUSTERED ([ID])
CREATE NONCLUSTERED INDEX [ix_dates] ON [#sargme] ([DateCol1], [DateCol2])

जो मैं बार-बार देखूंगा, वह कुछ इस तरह है:

/*definitely not sargable*/
SELECT
    * ,
    DATEDIFF(DAY, [s].[DateCol1], [s].[DateCol2])
FROM
    [#sargme] AS [s]
WHERE
    DATEDIFF(DAY, [s].[DateCol1], [s].[DateCol2]) >= 48;

... जो निश्चित रूप से SARGable नहीं है। यह एक इंडेक्स स्कैन में परिणाम देता है, सभी 1000 पंक्तियों को पढ़ता है, अच्छा नहीं। अनुमानित पंक्तियाँ बदबू मारती हैं। आप इसे उत्पादन में कभी नहीं डालेंगे।

नहीं सर, मुझे यह पसंद नहीं आया।

यह अच्छा होगा यदि हम सीटीई को अमल में ला सकते हैं, क्योंकि इससे हमें, अच्छी तरह से और अधिक प्रभावी, तकनीकी बोलने में मदद मिलेगी। लेकिन नहीं, हमें ऊपर की तरह ही निष्पादन योजना मिलती है।

/*would be nice if it were sargable*/
WITH    [x] AS ( SELECT
                * ,
                DATEDIFF(DAY, [s].[DateCol1], [s].[DateCol2]) AS [ddif]
               FROM
                [#sargme] AS [s])
     SELECT
        *
     FROM
        [x]
     WHERE
        [x].[ddif] >= 48;

और हां, चूंकि हम स्थिरांक का उपयोग नहीं कर रहे हैं, इसलिए यह कोड कुछ भी नहीं बदलता है, और आधा SARGable भी नहीं है। कोई मज़ा नहीं। एक ही निष्पादन योजना।

/*not even half sargable*/
SELECT
    * ,
    DATEDIFF(DAY, [s].[DateCol1], [s].[DateCol2])
FROM
    [#sargme] AS [s]
WHERE
    [s].[DateCol2] >= DATEADD(DAY, 48, [s].[DateCol1])

यदि आप भाग्यशाली महसूस कर रहे हैं, और आप अपने कनेक्शन स्ट्रिंग्स में सभी एएनएसआई सेट विकल्पों का पालन कर रहे हैं, तो आप एक गणना कॉलम जोड़ सकते हैं, और उस पर खोज कर सकते हैं ...

ALTER TABLE [#sargme] ADD [ddiff] AS 
DATEDIFF(DAY, DateCol1, DateCol2) PERSISTED

CREATE NONCLUSTERED INDEX [ix_dates2] ON [#sargme] ([ddiff], [DateCol1], [DateCol2])

SELECT [s].[ID] ,
       [s].[DateCol1] ,
       [s].[DateCol2]
FROM [#sargme] AS [s]
WHERE [ddiff] >= 48

यह आपको तीन प्रश्नों के साथ एक इंडेक्स की तलाश में मिलेगा। अजीब आदमी है जहाँ हम DateCol1 में 48 दिन जोड़ते हैं। साथ क्वेरी DATEDIFFमें WHEREखंड, CTEगणना स्तंभ पर विधेय के साथ, और अंतिम क्वेरी तुम सब बहुत अच्छे अनुमान के साथ एक बहुत अच्छे योजना सब देते हैं, और।

मैं इसके साथ रह सकता था।

जो मुझे इस सवाल पर ले जाता है: एक ही प्रश्न में, क्या इस खोज को करने के लिए एक SARGable तरीका है?

कोई टेम्‍परेचर टेबल नहीं, कोई टेबल वैरिएबल नहीं, टेबल स्ट्रक्चर में कोई फेरबदल नहीं और न ही कोई नजारा।

मैं सेल्फ-जॉइन, सीटीई, सबक्वेरी या डेटा के साथ कई पास के साथ ठीक हूं। SQL सर्वर के किसी भी संस्करण के साथ काम कर सकते हैं।

गणना किए गए कॉलम से बचना एक कृत्रिम सीमा है क्योंकि मैं किसी अन्य चीज़ की तुलना में क्वेरी समाधान में अधिक रुचि रखता हूं।

जवाबों:


16

बस इसे जल्दी से जोड़ना इसलिए यह एक उत्तर के रूप में मौजूद है (हालांकि मुझे पता है कि यह वह उत्तर नहीं है जो आप चाहते हैं)।

एक अनुक्रमित गणना कॉलम आमतौर पर इस प्रकार की समस्या का सही समाधान है।

यह:

  • एक अनुक्रमिक अभिव्यक्ति को विधेय बनाता है
  • बेहतर आत्मीयता आकलन के लिए स्वचालित आँकड़े बनाने की अनुमति देता है
  • बेस टेबल में कोई जगह लेने की जरूरत नहीं है

उस अंतिम बिंदु पर स्पष्ट होने के लिए, गणना किए गए कॉलम को इस मामले में बनाए रखने की आवश्यकता नहीं है :

-- Note: not PERSISTED, metadata change only
ALTER TABLE #sargme
ADD DayDiff AS DATEDIFF(DAY, DateCol1, DateCol2);

-- Index the expression
CREATE NONCLUSTERED INDEX index_name
ON #sargme (DayDiff)
INCLUDE (DateCol1, DateCol2);

अब प्रश्न:

SELECT
    S.ID,
    S.DateCol1,
    S.DateCol2,
    DATEDIFF(DAY, S.DateCol1, S.DateCol2)
FROM
    #sargme AS S
WHERE
    DATEDIFF(DAY, S.DateCol1, S.DateCol2) >= 48;

... निम्नलिखित तुच्छ योजना देता है :

निष्पादन योजना

जैसा कि मार्टिन स्मिथ ने कहा, यदि आपके पास गलत सेट विकल्पों का उपयोग करके कनेक्शन हैं, तो आप एक नियमित कॉलम बना सकते हैं और ट्रिगर का उपयोग करके गणना मूल्य बनाए रख सकते हैं।

यह सब केवल वास्तव में मायने रखता है (कोड को एक तरफ चुनौती देना) अगर निश्चित रूप से हल करने के लिए एक वास्तविक समस्या है, जैसा कि हारून अपने जवाब में कहते हैं ।

यह सोचने में मज़ेदार है, लेकिन मुझे इस बात को जानने का कोई तरीका नहीं है कि आप सवाल में अड़चनें क्या हैं। ऐसा लगता है कि किसी भी इष्टतम समाधान के लिए किसी प्रकार की नई डेटा संरचना की आवश्यकता होगी; निकटतम हमारे पास 'फ़ंक्शन इंडेक्स' सन्निकटन है जो ऊपर दिए गए गैर-संगणित गणना कॉलम पर एक इंडेक्स द्वारा प्रदान किया गया है।


12

SQL सर्वर समुदाय में सबसे बड़े नामों में से कुछ का उपहास करते हुए, मैं अपनी गर्दन को बाहर निकालने और कहने के लिए जा रहा हूं, नहीं।

आपकी क्वेरी SARGable होने के लिए, आपको मूल रूप से एक क्वेरी का निर्माण करना होगा, जो एक इंडेक्स में लगातार पंक्तियों की एक श्रृंखला में एक पंक्ति को इंगित कर सके । सूचकांक के साथ ix_dates, पंक्तियों के बीच की तारीख अंतर द्वारा आदेश दिया नहीं कर रहे हैं DateCol1और DateCol2, इसलिए अपने लक्ष्य पंक्तियों सूचकांक में कहीं भी फैला हुआ जा सकता है।

सेल्फ-जॉइन, मल्टीपल पास आदि सभी में समान है कि वे कम से कम एक इंडेक्स स्कैन को शामिल करें, हालांकि (नेस्टेड लूप) जॉइन एक इंडेक्स सीक का उपयोग कर सकते हैं। लेकिन मैं यह नहीं देख सकता कि स्कैन को खत्म करना कैसे संभव होगा।

अधिक सटीक पंक्ति अनुमान प्राप्त करने के लिए, तिथि अंतर पर कोई आंकड़े नहीं हैं।

निम्नलिखित, काफी बदसूरत पुनरावर्ती CTE निर्माण तकनीकी रूप से पूरी तालिका को स्कैन करने को समाप्त कर देता है, हालांकि यह एक नेस्टेड लूप जॉइन करता है और सूचकांक (संभावित रूप से बहुत बड़ी) संख्या की तलाश करता है।

DECLARE @from date, @count int;
SELECT TOP 1 @from=DateCol1 FROM #sargme ORDER BY DateCol1;
SELECT TOP 1 @count=DATEDIFF(day, @from, DateCol1) FROM #sargme WHERE DateCol1<=DATEADD(day, -48, {d '9999-12-31'}) ORDER BY DateCol1 DESC;

WITH cte AS (
    SELECT 0 AS i UNION ALL
    SELECT i+1 FROM cte WHERE i<@count)

SELECT b.*
FROM cte AS a
INNER JOIN #sargme AS b ON
    b.DateCol1=DATEADD(day, a.i, @from) AND
    b.DateCol2>=DATEADD(day, 48+a.i, @from)
OPTION (MAXRECURSION 0);

यह DateCol1तालिका में प्रत्येक के साथ एक इंडेक्स स्पूल बनाता है , फिर उनमें से प्रत्येक के लिए एक इंडेक्स सीक (रेंज स्कैन) करता है DateCol1और DateCol2जो कम से कम 48 दिन आगे हैं।

अधिक IOs, थोड़ा लंबा निष्पादन समय, पंक्ति अनुमान अभी भी बंद है, और पुनरावृत्ति के कारण समानांतर होने का शून्य मौका: मैं अनुमान लगा रहा हूं कि यह क्वेरी संभवतः उपयोगी हो सकती है यदि आपके पास अपेक्षाकृत कुछ विशिष्ट, लगातार, भीतर बहुत बड़ी संख्या है। DateCol1(नीचे देखा की संख्या रखते हुए)।

पागल पुनरावर्ती CTE क्वेरी योजना


9

मैंने निराला विविधताओं की एक गुच्छा की कोशिश की, लेकिन आपके किसी भी संस्करण को बेहतर नहीं पाया। मुख्य समस्या यह है कि दिनांक 1 और दिनांक 2 को एक साथ क्रमबद्ध करने के संदर्भ में आपका सूचकांक कैसा दिखता है। पहला स्तंभ एक अच्छी आश्रित रेखा में होने जा रहा है, जबकि उनके बीच का अंतर बहुत दांतेदार होने वाला है। आप चाहते हैं कि यह एक फ़नल की तरह दिखे जिस तरह से यह वास्तव में होगा:

Date1    Date2
-----    -------
*             *
*             *
*              *
 *       * 
 *        *
 *         *
  *      *
  *           *

वहाँ वास्तव में कोई रास्ता नहीं है कि मैं दो बिंदुओं के बीच एक निश्चित डेल्टा (या डेल्टास की सीमा) के लिए उस खोज योग्य बनाने के बारे में सोच सकता हूं। और मेरा मतलब है कि एक एकल खोज जिसे एक बार + रेंज स्कैन किया गया है, न कि हर पंक्ति के लिए निष्पादित की गई तलाश। इसमें कुछ बिंदु पर एक स्कैन और / या एक प्रकार शामिल होगा, और ये ऐसी चीजें हैं जिनसे आप स्पष्ट रूप से बचना चाहते हैं। यह बहुत बुरा है आप फ़िल्टर किए गए अनुक्रमित में DATEADD/ जैसे भावों का उपयोग नहीं कर सकते हैं DATEDIFF, या किसी भी संभावित स्कीमा संशोधनों को निष्पादित कर सकते हैं जो कि तिथि के उत्पाद पर एक प्रकार की अनुमति देगा (जैसे सम्मिलित / अपडेट समय पर डेल्टा की गणना)। जैसा कि, यह उन मामलों में से एक लगता है जहां एक स्कैन वास्तव में इष्टतम पुनर्प्राप्ति विधि है।

आपने कहा कि यह क्वेरी मज़ेदार नहीं थी, लेकिन यदि आप करीब से देखते हैं, तो यह अब तक का सबसे अच्छा है (और अगर आप गणना स्केलर आउटपुट को छोड़ दें तो और भी बेहतर होगा):

SELECT
    * ,
    DATEDIFF(DAY, [s].[DateCol1], [s].[DateCol2])
FROM
    [#sargme] AS [s]
WHERE
    [s].[DateCol2] >= DATEADD(DAY, 48, [s].[DateCol1])

कारण यह है कि DATEDIFFसंभावित रूप से बचने से सूचकांक में केवल गैर-प्रमुख कुंजी कॉलम के खिलाफ गणना की तुलना में कुछ सीपीयू को हिला दिया जाता है, और कुछ बुरा निहितार्थ रूपांतरणों से भी बचा जाता है datetimeoffset(7)(मुझसे मत पूछिए कि वे क्यों हैं, लेकिन वे हैं)। यहाँ DATEDIFFसंस्करण है:

<Predicate>
<ScalarOperator ScalarString = "datediff (दिन, CONVERT_IMPLICIT (datetimeoffset (7), [splunge]। [Dbo] 7), [फुंसी] [dbo]। [sargme]। [DateCol2] [[s]। [DateCol2], 0))> = (48) ">

और यहाँ एक बिना है DATEDIFF:

<Predicate>
<ScalarOperator ScalarString = "[अलग होना]। [dbo]। [sargme]। [DateCol2] [s] के रूप में। [DateCol2]>" Dateadd (दिन), (48), [splunge] [dbo]। sargme]। [DateCol1] [s]। [DateCol1]) ">

इसके अलावा, मैंने अवधि के संदर्भ में थोड़ा बेहतर परिणाम पाया जब मैंने सूचकांक को केवल शामिल करने के लिए बदल दिया DateCol2(और जब दोनों सूचकांक मौजूद थे, तो SQL सर्वर ने हमेशा एक कुंजी के साथ एक को चुना और एक में कॉलम बनाम मल्टी-की शामिल है)। इस क्वेरी के लिए, चूंकि हमें रेंज को खोजने के लिए सभी पंक्तियों को स्कैन करना है, वैसे भी कुंजी के भाग के रूप में दूसरी तिथि का कॉलम होने और किसी भी तरह से सॉर्ट करने का कोई लाभ नहीं है। और जब मुझे पता है कि हम यहां कोई खोज नहीं कर सकते हैं, तो मुख्य रूप से प्रमुख स्तंभ के खिलाफ गणना के द्वारा एक प्राप्त करने की क्षमता में बाधा नहीं होने के बारे में स्वाभाविक रूप से अच्छी भावना है , और केवल उन्हें माध्यमिक या शामिल कॉलम के खिलाफ प्रदर्शन करना है।

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

और यह सब कितना मायने रखता है? मुझे नहीं पता। मैंने तालिका को 10 मिलियन पंक्तियों में बनाया और उपरोक्त सभी क्वेरी विविधताएं अभी भी एक सेकंड के तहत पूरी की हैं। और यह एक लैपटॉप पर एक वीएम पर है (दी गई, एसएसडी के साथ)।


3

मेरे द्वारा किए जाने वाले तरीकों में से सभी यह सुनिश्चित करने के लिए हैं कि कहां-कहां खंड-योग्य हैं, जटिल हैं और ऐसा लगता है कि इंडेक्स की दिशा में काम करना एक साधन के बजाय एक अंतिम लक्ष्य है। तो, नहीं, मुझे नहीं लगता कि यह (व्यावहारिक रूप से) संभव है।

मुझे यकीन नहीं था कि "कोई तालिका संरचना नहीं बदल रहा है" का मतलब कोई अतिरिक्त अनुक्रमित नहीं है। यहाँ एक समाधान है जो पूरी तरह से सूचकांक स्कैन से बचता है, लेकिन तालिका में न्यूनतम / अधिकतम श्रेणी के दिनांक मानों में प्रत्येक संभावित DateCol1 तिथि के लिए एक यानी अलग-अलग सूचकांक का एक बहुत कुछ होता है। (डैनियल के विपरीत जिसके परिणामस्वरूप प्रत्येक विशिष्ट तिथि के लिए एक तलाश होती है जो वास्तव में तालिका में दिखाई देती है)। यह सैद्धांतिक रूप से समानता बी / सी के लिए एक उम्मीदवार है यह पुनरावृत्ति से बचा जाता है। लेकिन ईमानदारी से, एक डेटा वितरण को देखने के लिए कठिन है, जहां यह बात सिर्फ स्कैनिंग और डेटेडिफ़ की तुलना में तेज़ है। (शायद आ सच में उच्च डीओपी?) और ... कोड बदसूरत है। मुझे लगता है कि यह प्रयास "मानसिक व्यायाम" के रूप में गिना जाता है।

--Add this index to avoid the scan when determining the @MaxDate value
--CREATE NONCLUSTERED INDEX [ix_dates2] ON [#sargme] ([DateCol2]);
DECLARE @MinDate DATE, @MaxDate DATE;
SELECT @MinDate=DateCol1 FROM (SELECT TOP 1 DateCol1 FROM #sargme ORDER BY DateCol1 ASC) ss;
SELECT @MaxDate=DateCol2 FROM (SELECT TOP 1 DateCol2 FROM #sargme ORDER BY DateCol2 DESC) ss;

--Used 44 just to get a few more rows to test my logic
DECLARE @DateDiffSearchValue INT = 44, 
    @MinMaxDifference INT = DATEDIFF(DAY, @MinDate, @MaxDate);

--basic data profile in the table
SELECT [MinDate] = @MinDate, 
        [MaxDate] = @MaxDate, 
        [MinMaxDifference] = @MinMaxDifference, 
        [LastDate1SearchValue] = DATEADD(DAY, 0-@DateDiffSearchValue, @MaxDate);

;WITH rn_base AS (
SELECT [col1] = 0
        UNION ALL SELECT 0
        UNION ALL SELECT 0
        UNION ALL SELECT 0
),
rn_1 AS (
    SELECT t0.col1 FROM rn_base t0
        CROSS JOIN rn_base t1
        CROSS JOIN rn_base t2
        CROSS JOIN rn_base t3
),
rn_2 AS (
    SELECT rn = ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
    FROM rn_1 t0
        CROSS JOIN rn_1 t1
),
candidate_searches AS (
    SELECT 
        [Date1_EqualitySearch] = DATEADD(DAY, t.rn-1, @MinDate),
        [Date2_RangeSearch] = DATEADD(DAY, t.rn-1+@DateDiffSearchValue, @MinDate)
    FROM rn_2 t
    WHERE DATEADD(DAY, t.rn-1, @MinDate) <= DATEADD(DAY, 0-@DateDiffSearchValue, @MaxDate)
    /* Of course, ignore row-number values that would result in a
       Date1_EqualitySearch value that is < @DateDiffSearchValue days before @MaxDate */
)
--select * from candidate_searches

SELECT c.*, xapp.*, dd_rows = DATEDIFF(DAY, xapp.DateCol1, xapp.DateCol2)
FROM candidate_searches c
    cross apply (
        SELECT t.*
        FROM #sargme t
        WHERE t.DateCol1 = c.date1_equalitysearch
        AND t.DateCol2 >= c.date2_rangesearch
    ) xapp
ORDER BY xapp.ID asc --xapp.DateCol1, xapp.DateCol2 

3

सामुदायिक विकी उत्तर मूल रूप से प्रश्न लेखक द्वारा प्रश्न को संपादित करने के रूप में जोड़ा गया है

इसे थोड़ा बैठने के लिए, और कुछ वास्तव में होशियार लोगों को चिंघाड़ते हुए, इस पर मेरा प्रारंभिक विचार सही लगता है: इस क्वेरी को स्तंभ जोड़ने के बिना लिखने के लिए कोई समझदार और SARGable तरीका नहीं है, या तो गणना की जाती है, या किसी अन्य तंत्र के माध्यम से बनाए रखा जाता है, अर्थात् चलाता।

मैंने कुछ अन्य चीजों की कोशिश की, और मेरी कुछ अन्य टिप्पणियां हैं जो किसी के पढ़ने के लिए दिलचस्प हो सकती हैं या नहीं।

सबसे पहले, अस्थायी तालिका के बजाय एक नियमित तालिका का उपयोग करके सेटअप को फिर से चलाना

  • भले ही मैं उनकी प्रतिष्ठा जानता हूं, मैं मल्टी-कॉलम के आंकड़ों को आज़माना चाहता था। वे बेकार थे।
  • मैं देखना चाहता था कि किन आंकड़ों का इस्तेमाल किया गया

यहाँ नया सेटअप है:

USE [tempdb]
SET NOCOUNT ON  

DBCC FREEPROCCACHE

IF OBJECT_ID('tempdb..sargme') IS NOT NULL
BEGIN
DROP TABLE sargme
END

SELECT TOP 1000
IDENTITY (BIGINT, 1,1) AS ID,
CAST(DATEADD(DAY, [m].[severity] * -1, GETDATE()) AS DATE) AS [DateCol1],
CAST(DATEADD(DAY, [m].[severity], GETDATE()) AS DATE) AS [DateCol2]
INTO sargme
FROM sys.[messages] AS [m]

ALTER TABLE [sargme] ADD CONSTRAINT [pk_whatever] PRIMARY KEY CLUSTERED ([ID])
CREATE NONCLUSTERED INDEX [ix_dates] ON [sargme] ([DateCol1], [DateCol2])

CREATE STATISTICS [s_sargme] ON [sargme] ([DateCol1], [DateCol2])

फिर, पहली क्वेरी चलाने पर, यह पहले की तरह ix_dates इंडेक्स और स्कैन का उपयोग करता है। यहां कोई बदलाव नहीं। यह बेमानी लगता है, लेकिन मेरे साथ रहना।

SELECT
    * ,
    DATEDIFF(DAY, [s].[DateCol1], [s].[DateCol2])
FROM
    [sargme] AS [s]
WHERE
    DATEDIFF(DAY, [s].[DateCol1], [s].[DateCol2]) >= 48

CTE क्वेरी फिर से चलाएँ, अभी भी वही ...

WITH    [x] AS ( SELECT
                * ,
                DATEDIFF(DAY, [s].[DateCol1], [s].[DateCol2]) AS [ddif]
               FROM
                [sargme] AS [s])
     SELECT
        *
     FROM
        [x]
     WHERE
        [x].[ddif] >= 48;

ठीक है! फिर से आधी-अधूरी क्वेरी न चलाएं:

SELECT
    * ,
    DATEDIFF(DAY, [s].[DateCol1], [s].[DateCol2])
FROM
    [sargme] AS [s]
WHERE
    [s].[DateCol2] >= DATEADD(DAY, 48, [s].[DateCol1])

अब गणना किए गए कॉलम को जोड़ें, और गणना किए गए कॉलम को हिट करने वाले क्वेरी के साथ तीनों को फिर से चलाएं:

ALTER TABLE [sargme] ADD [ddiff] AS 
DATEDIFF(DAY, DateCol1, DateCol2) PERSISTED

CREATE NONCLUSTERED INDEX [ix_dates2] ON [sargme] ([ddiff], [DateCol1], [DateCol2])

SELECT [s].[ID] ,
       [s].[DateCol1] ,
       [s].[DateCol2]
FROM [sargme] AS [s]
WHERE [ddiff] >= 48

अगर तुम मेरे साथ यहाँ तक रहे, धन्यवाद। यह पोस्ट का दिलचस्प अवलोकन हिस्सा है।

फैबियानो अमोरिम द्वारा एक अविवादित ट्रेस ध्वज के साथ एक क्वेरी चलाना यह देखने के लिए कि प्रत्येक क्वेरी का उपयोग करने वाले आंकड़े बहुत अच्छे हैं। यह देखकर कि कोई भी योजना किसी सांख्यिकी ऑब्जेक्ट को तब तक नहीं छूती है जब तक कि गणना किए गए कॉलम को बनाया और अनुक्रमित नहीं किया गया हो।

क्या खूनखराबा

हेक, यहां तक ​​कि क्वेरी जो कि गणना किए गए कॉलम को हिट करती है, केवल तब तक एक आँकड़े ऑब्जेक्ट को नहीं छूती है जब तक कि मैंने इसे कुछ बार नहीं चलाया और इसे सरल पैरामीटराइजेशन मिला। इसलिए भले ही वे सभी शुरू में ix_dates सूचकांक को स्कैन करते थे, लेकिन उन्होंने उनके लिए उपलब्ध किसी भी आँकड़े ऑब्जेक्ट के बजाय हार्ड-कोडेड कार्डिनैलिटी अनुमान (तालिका का 30%) का उपयोग किया।

एक अन्य बिंदु जो यहां पर एक भौं उठा था, वह यह है कि जब मैंने केवल गैर-अनुक्रमित सूचकांक को जोड़ा था, तो दोनों ही स्तंभों पर गैर-अनुक्रमित सूचकांक का उपयोग करने के बजाय क्वेरी ने सभी HEAP को स्कैन किया।

प्रतिक्रिया देने वाले सभी लोगों का शुक्रिया। तुम सब अद्भुत हो।

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