2010-09-29 38 views
6

साथ SQLServer में विचारों के खिलाफ में शामिल होने से मैं एक जटिल राय यह है कि मैं प्राथमिक कुंजी है कि एक मेज है कि दो अस्थायी अंक के बीच संशोधित किया गया है में पंक्तियों से संकेत मिलता है की एक सूची खींचने के लिए उपयोग किया है।अजीब क्वेरी अनुकूलक व्यवहार

यह दृश्य 13 संबंधित टेबल क्वेरी और एक बदलाव का मेज पर देखने के निर्धारित करने के लिए एक इकाई "गंदे" है या नहीं करने के लिए है।

यहां तक ​​कि यह सब हो रहा, एक साधारण क्वेरी कर साथ

:

select * from vwDirtyEntities; 

केवल 2 सेकंड लेता है।

हालांकि, अगर मैं इसे

select 
    e.Name 
from 
    Entities e 
     inner join vwDirtyEntities de 
      on e.Entity_ID = de.Entity_ID 

करने के लिए बदल यह 1.5 मिनट लगते हैं।

हालांकि, अगर मैं ऐसा करते हैं:

declare @dirtyEntities table 
(
    Entity_id uniqueidentifier; 
) 

insert into @dirtyEntities 
    select * from vwDirtyEntities; 


select 
    e.Name 
from 
    Entities e 
     inner join @dirtyEntities de 
      on e.Entity_ID = de.Entity_ID 

मैं केवल 2 सेकंड में एक ही परिणाम मिलता है।

इससे मुझे विश्वास होता है कि SQLServer एक पंक्ति योजना बनाने के बजाय प्रति पंक्ति के दृश्य का मूल्यांकन कर रहा है जिसमें दृश्य में अन्य शामिल होने के लिए उपरोक्त एकल शामिल होने में शामिल होना शामिल है।

ध्यान दें कि मैं, इस दृश्य से सेट पूर्ण परिणाम के खिलाफ शामिल करना चाहते हैं, क्योंकि यह केवल चाबियाँ मैं आंतरिक रूप से चाहते हैं बाहर फिल्टर।

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

तो, दृश्य परिणामों को कैश करने के लिए तालिका चर का उपयोग करने के अलावा, क्या एसक्यूएल सर्वर को शामिल होने का मूल्यांकन करते समय दृश्य को कैश करने का कोई तरीका है? मैंने शामिल होने के क्रम को बदलने की कोशिश की (दृश्य से चुनें और संस्थाओं के खिलाफ शामिल हों), हालांकि इससे कोई फर्क नहीं पड़ता।

दृश्य खुद भी बहुत ही कुशल है, और कोई जगह नहीं अनुकूलन करने के लिए नहीं है।

उत्तर

5

एक दृश्य के बारे में जादुई कुछ भी नहीं है। यह एक मैक्रो है जो फैलता है। ऑप्टिमाइज़र निर्णय लेता है जब दृश्य को मुख्य क्वेरी में विस्तारित करने के लिए कहा जाता है।

मैं अपनी पोस्ट में अन्य बिंदुओं को संबोधित करेंगे:

  • आप एक अनुक्रमित दृश्य की संभावना से इनकार किया है। एक दृश्य केवल एक असतत इकाई जब यह

  • एसक्यूएल सर्वर अनुक्रमणित है अपने आप पर एक RBAR क्वेरी ऐसा कभी नहीं होगा हो सकता है। केवल डेवलपर्स लूप लिख सकते हैं।

  • कैशिंग की कोई अवधारणा नहीं है: प्रत्येक क्वेरी के नवीनतम डेटा का उपयोग करता है जब तक आप अस्थायी तालिकाओं

  • आप दृश्य जो आप तय कर लिया है बहुत ही कुशल है का उपयोग कर पर जोर देते हैं का उपयोग करें।लेकिन पता नहीं कैसे विचारों अनुकूलक द्वारा इलाज कर रहे हैं और यह टेबल

  • एसक्यूएल कथात्मक है: आदेश आमतौर पर कोई फर्क नहीं पड़ता

  • कई गंभीर डीबी डेवलपर क्योंकि सीमाओं के विचारों का प्रयोग नहीं करते में शामिल होने के इस तरह: वे पुन: प्रयोज्य नहीं हैं क्योंकि वे मैक्रोज़

संपादित करें, एक और संभावना। SQL Server 2005 पर Predicate pushing. यानी, SQL सर्वर जॉइन स्थिति को "गहरी" दृश्य में धक्का नहीं दे सकता है।

+0

यदि आप ओमग पोनीज़ के लिए पोस्ट एडिट इतिहास देखते हैं, तो आप देखेंगे कि मैंने एक साधारण टिप्पणी (अभी भी वहां) के साथ जवाब दिया है, और वह बिना किसी चीज से चला गया। संदर्भ के लिए, यहां उनका मूल उत्तर दिया गया है: http://stackoverflow.com/revisions/2be5678d-7d09-4c14-9043-c4769f9f9c03/view-source। – FlySwat

+0

और यहां मेरी टिप्पणी के बाद उन्होंने संपादित किया है: http://stackoverflow.com/revisions/0d5a1cb1-1f89-4fba-96f4-c270d0543805/view-source। मैंने कभी हमला नहीं किया, वह बाहर निकलना शुरू कर दिया। – FlySwat

+0

मामले में शामिल होने के संबंध में कोई फर्क नहीं पड़ता। यह सिद्धांत में सच हो सकता है, लेकिन व्यावहारिक रूप से मैंने स्पष्ट रूप से फायदेमंद होने के लिए शामिल होने का पुन: आदेश देखा है, आमतौर पर क्योंकि यह डेटाबेस को डेटा के बड़े सेट को त्यागने की अनुमति देता है जो अन्य जोड़ों का मूल्यांकन करने से पहले मेल नहीं खाता है। – FlySwat

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