मुझे निम्नलिखित की तरह एक क्वेरी मिली है:
DELETE FROM tblFEStatsBrowsers WHERE BrowserID NOT IN (
SELECT DISTINCT BrowserID FROM tblFEStatsPaperHits WITH (NOLOCK) WHERE BrowserID IS NOT NULL
)
tblFEStatsBrowsers को 553 पंक्तियाँ मिली हैं।
tblFEStatsPaperHits को 47.974.301 पंक्तियाँ मिली हैं।
tblFEStatsBrowsers:
CREATE TABLE [dbo].[tblFEStatsBrowsers](
[BrowserID] [smallint] IDENTITY(1,1) NOT NULL,
[Browser] [varchar](50) NOT NULL,
[Name] [varchar](40) NOT NULL,
[Version] [varchar](10) NOT NULL,
CONSTRAINT [PK_tblFEStatsBrowsers] PRIMARY KEY CLUSTERED ([BrowserID] ASC)
)
tblFEStatsPaperHits:
CREATE TABLE [dbo].[tblFEStatsPaperHits](
[PaperID] [int] NOT NULL,
[Created] [smalldatetime] NOT NULL,
[IP] [binary](4) NULL,
[PlatformID] [tinyint] NULL,
[BrowserID] [smallint] NULL,
[ReferrerID] [int] NULL,
[UserLanguage] [char](2) NULL
)
TblFEStatsPaperHits पर एक संकुल सूचकांक है जिसमें BrowserID शामिल नहीं है। इस प्रकार आंतरिक क्वेरी करने के लिए tblFEStatsPaperHits की पूर्ण तालिका स्कैन की आवश्यकता होगी - जो पूरी तरह से ठीक है।
वर्तमान में, tblFEStatsBrowsers में प्रत्येक पंक्ति के लिए एक पूर्ण स्कैन निष्पादित किया गया है, जिसका अर्थ है कि मुझे tblFEStatsPaperHits की 553 पूर्ण तालिका स्कैन मिली है।
सिर्फ WHIS EXISTS को फिर से शुरू करने से योजना में बदलाव नहीं होता है:
DELETE FROM tblFEStatsBrowsers WHERE NOT EXISTS (
SELECT * FROM tblFEStatsPaperHits WITH (NOLOCK) WHERE BrowserID = tblFEStatsBrowsers.BrowserID
)
हालाँकि, जैसा कि एडम मैकहानिक ने सुझाव दिया था, एचएएसएच जोइन विकल्प को जोड़ने से इष्टतम निष्पादन योजना (tblFEStatsPaperHits का सिर्फ एक स्कैन) होती है:
DELETE FROM tblFEStatsBrowsers WHERE NOT EXISTS (
SELECT * FROM tblFEStatsPaperHits WITH (NOLOCK) WHERE BrowserID = tblFEStatsBrowsers.BrowserID
) OPTION (HASH JOIN)
अब यह उतना ठीक नहीं है कि इसे कैसे ठीक किया जाए - मैं या तो विकल्प (एचएएसएच जॉइन) का उपयोग कर सकता हूं या मैन्युअल रूप से एक टेबुल टेबल बना सकता हूं। मैं अधिक आश्चर्यचकित हूं कि क्वेरी ऑप्टिमाइज़र कभी भी उस योजना का उपयोग क्यों करेगा जो वर्तमान में करता है।
चूंकि QO के ब्राउज़रआईडी कॉलम पर कोई आँकड़े नहीं हैं, इसलिए मैं अनुमान लगा रहा हूँ कि यह सबसे खराब मान रहा है - 50 मिलियन अलग-अलग मूल्य, इस प्रकार काफी बड़े इन-मेमोरी / टेम्पर्ड वर्कटेबल की आवश्यकता होती है। जैसे, tblFEStatsBrowsers में प्रत्येक पंक्ति के लिए स्कैन करने के लिए सबसे सुरक्षित तरीका है। दो तालिकाओं में ब्राउज़रआईडी कॉलम के बीच कोई विदेशी कुंजी संबंध नहीं है, इसलिए QO tblFEStatsBrowsers से किसी भी जानकारी को काट नहीं सकता है।
क्या यह इतना सरल है, जितना लगता है, इसका कारण है?
अपडेट 1
कुछ आंकड़े देने के लिए: विकल्प (HASH JOIN):
208.711 तार्किक रीड (12 स्कैन)
विकल्प (LOOP JOIN, HASH GROUP):
11.008.698 तार्किक रीड (~ ब्राउजर प्रति स्कैन (339))
कोई विकल्प नहीं:
11.008.775 तार्किक रीड (~ ब्राउज़रआईडी प्रति स्कैन (339))
अद्यतन 2
उत्कृष्ट जवाब, आप सभी को - धन्यवाद! बस एक लेने के लिए कठिन है। हालांकि मार्टिन पहले था और रेमस एक उत्कृष्ट समाधान प्रदान करता है, मुझे इसे विवरण पर मानसिक रूप से जाने के लिए कीवी को देना होगा :)