2009-10-02 15 views
8

हम एक ओआरएम का उपयोग कर रहे हैं जो .NET से SQL सर्वर की sp_executesql संग्रहीत प्रक्रिया से कॉल निष्पादित कर रहा है।एसक्यूएल क्वेरी .NET कोड से धीमी है, लेकिन इंटरैक्टिव रूप से

जब संग्रहीत प्रो .NET से कहा जाता है, तो हमें टाइमआउट अपवाद मिलता है।

प्रोफाइलर को देखते हुए, मैं देख सकता हूं कि क्वेरी वास्तव में निष्पादित करने में काफी समय ले रही है। तब भी वह अच्छे कार्यान्वित अगर मैं कॉपी और क्वेरी कि SQL प्रबंधन स्टूडियो में बाहर समय है पेस्ट करें और इसे सहभागी निष्पादित:

क्वेरी अनिवार्य है:

exec sp_executesql N'SELECT DISTINCT 
FROM [OurDatabase].[dbo].[Contract] [LPLA_1]) [LPA_L1] 
LEFT JOIN [OurDatabase].[dbo].[Customer] [LPA_L2] ON [LPA_L2].[Customer_ID]=[LPA_L1].[CustomerId] AND [LPA_L2].[Data]=[LPA_L1].[Data]) 
WHERE ((((([LPA_L1].[DealerId] = @DealerId1)) 
AND ([LPA_L2].[Last_Name] = @LastName2))))',N'@DealerId1 varchar(18),@LastName2 varchar(25)',@DealerId1='1234',@LastName2='SMITH' 

मेरे लिए भ्रामक हिस्सा यह है।

क्या किसी को पता है कि .NET कोड के माध्यम से निष्पादित होने पर एक ही क्वेरी में काफी समय क्यों लगेगा? (मैं इसे पुन: उत्पन्न करने में सक्षम हूं - कोड से निष्पादित क्वेरी लगातार बार-बार होती है, और क्वेरी निष्पादित रूप से निष्पादित रूप से ठीक से काम करती है।)

किसी भी मदद की सराहना की जाती है। धन्यवाद!

+0

आप कितने डेटा लौट रहे हैं? यदि हजारों और हजारों लाइनें हैं तो परिणामस्वरूप कंप्यूटर पर वायर को धक्का देने में समय लग सकता है। – Miles

+0

क्या क्वेरी बहुत सारे डेटा लौटाती है? क्या प्रोग्राम केस में शामिल सर्वर और क्लाइंट के बीच कोई डेटा भेज रहा है जो इंटरैक्टिव मोड में नहीं होता है? हमारे परीक्षण मामले में – quosoo

+0

तीन। इसके अलावा, डीलरिड और लास्ट_नाम में इंडेक्स हैं। –

उत्तर

0

क्या डीलर आईडी या अंतिम नाम nvarchar (अलग-अलग वर्चुअल पैरामीटर से टाइप किया गया है)?

इससे पूरे इंडेक्स का रूपांतरण हो सकता है। यदि आपको यह मामला लगता है, तो एक टिप्पणी छोड़ दो और मैं अधिक विस्तार से समझाऊंगा।

+0

नहीं, दुर्भाग्यवश, वे डेटाबेस में दोनों वर्कर्स हैं। –

4

एक बात मैंने कुछ बार देखा है यदि आपके पास अनुक्रमित क्षेत्र पर क्वेरी पैरामीटर के लिए nvarchar और varchar प्रकारों के बीच कोई मेल नहीं है। ऐसा तब हो सकता है जब आप अपने डेटाबेस में वर्कर का उपयोग करें और अपने पैरामीटर के प्रकार को .Net में स्पष्ट रूप से सेट न करें, जो डिफ़ॉल्ट रूप से nvarchar मान लेगा।

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

+0

यह क्यों मायने रखता है कि SQL एमजीएमटी स्टूडियो की बजाय क्वेरी .NET से चलती है? –

+0

क्या आपने मेरी पोस्ट पढ़ी? जब आप अपने sqlcommand ऑब्जेक्ट के लिए पैरामीटर बनाते हैं .Net (भले ही वह हिस्सा किसी ओआरएम द्वारा छिपा हुआ हो) और स्पष्ट रूप से यह नहीं बताएं कि उन पैरामीटर के प्रकार क्या हैं, नेट आपके लिए चुनेंगे और यह गलत चुन सकता है। नतीजा यह है कि यह बिल्कुल वही प्रश्न नहीं है। –

+0

हां, लेकिन एलेक्सवाल्कर एसक्यूएल एमजीएमटी स्टूडियो में प्रोफाइलर ==> से ली गई क्वेरी में चल रहा है, यह वही क्वेरी है जो SQL सर्वर अंततः उत्प्रेरक (.NET या Mgmt। Studio) के बावजूद चलाएगा। जब तक, कनेक्शन अलग-अलग कॉन्फ़िगर नहीं किया जाता है ... मेरे पास एक झुकाव है कि कनेक्शन क्या अंतर बनाता है। –

1

मुझे एक ही समस्या है, .NET से निष्पादित एक प्रक्रिया है जो बहुत अधिक समय लेती है (और बहुत सारी पंक्तियां नहीं लौटाती है)। मैं एसक्यूएल को एक स्ट्रिंग भेजता हूं: "exec_procedure @ पैरामीटर 1 = value1 निष्पादित करें" और मैं इसे कॉपी करता हूं और एसक्यूएल प्रबंधन स्टूडियो पर चलता हूं लेकिन वहां सब कुछ ठीक चलता है। इस मामले का भ्रष्ट यह है कि मेरी क्वेरी में मैं इसके कारण पैरामीटर मान से एक LETTER जोड़ या निकालता हूं। मैं बड़ी उलझन में हूं।

जानकारी के लिए, मैं पूर्ण पाठ अनुक्रमणिका और temp टेबल por paging का उपयोग कर रहा हूं, लेकिन जैसा कि मैंने कहा, वही QUERY (और मुझे यकीन है) एसक्यूएल प्रबंधन स्टूडियो में पूरी तरह से चलता है।

1

बस एक ही समस्या थी।

पुनर्निर्माण सूचकांक समस्या हल हो गई।

शायद समस्या वर्चर्स बनाम इंडेक्स होने वाले पैरामीटर के प्रकार में निहित है जो वर्चर कॉलम पर है ...?

1

मुझे लगता है कि ऐसा इसलिए है क्योंकि sp_executelsql संकलित क्वेरी योजनाओं का पुन: उपयोग करने के लिए है, इसलिए यह उसी क्वेरी को फिर से हिट करते समय पैरामीटर को फिर से स्नीफ नहीं करता है, इसलिए यह एक ऐसी योजना का उपयोग करने में समाप्त होता है जो बहुत धीमा हो सकता है (इच्छा वर्तमान पैरामीटर मानों के साथ आपको एक धीमी क्वेरी योजना क्यों बताएं)।ऐसा प्रतीत होता है कि sp_executesql इंडेक्स चुनने के लिए एक अलग विधि का उपयोग करता है और स्पष्ट रूप से यह एक सादे पाठ क्वेरी की तुलना में एक टूटी हुई विधि है।

sp_executesql के तहत 'कंपनी (एक टेबल)' के लिए तालिका अद्यतन क्या है, नेस्टेड लूप की एक श्रृंखला के माध्यम से खिलाया जाता है जबकि टेक्स्ट क्वेरी हैश मैचों की श्रृंखला के माध्यम से खिलाया जाता है। विचारों का निर्माण दो संस्करणों (जो मैं अपेक्षा करता हूं) के बीच समान दिखाई देता है। दुर्भाग्य से, शेष बहुत जटिल है और वे बीच में मूल रूप से अलग-अलग चीजें कर रहे हैं; यहां तक ​​कि "वास्तविक" निष्पादन योजना खींचने से क्वेरी के विभिन्न उप घटकों के लिए वास्तविक निष्पादन समय नहीं मिलता है। असल में, मुझे sp_executesql के लिए कुछ भी अलग-अलग चुनने का कोई कारण नहीं दिख रहा है, लेकिन यह विश्वसनीय रूप से एक धीमी योजना का निर्माण करता है।

पैरामीटर स्नीफिंग इसका समाधान है, इसलिए आपको पैरामीटर नामों का नाम बदलना चाहिए या आप कॉलम नामों को भी स्वैप कर सकते हैं, जहां क्लॉज जो sp_executesql को पुरानी धीमी योजना का उपयोग करने के बजाय क्वेरी प्लान को फिर से बनाने का कारण बनता है, बेशक यह है समाधान नहीं, लेकिन यह इतनी देर तक धीमी योजना को कैश नहीं करेगा।

सम्मान।

+0

धन्यवाद, यह सच दिखता है –

1

यहां मुझे जो मिला वह है। मेरे पास एक बहुत जटिल संग्रहित प्रो है जो हमेशा जानकारी की गणना करती है और डेटा को 8 कॉलम 17 पंक्ति मैट्रिक्स में रखती है क्योंकि इसे क्रिस्टल रिपोर्ट्स द्वारा हर महीने कहा जाता है/चलाया जाता है। प्रोड डेटाबेस 96 जीबी पागल फास्ट सर्वर पर था! हाल ही में इसे 32 जीबी आभासी मशीन में घटा दिया गया था। जबकि स्केल डाउन किया गया - इसने ऐप को कई तरीकों से धीमा कर दिया - जब तक कि कुछ इंडेक्स जोड़े नहीं गए।

फिर, महीने का समय इस 17 पंक्ति मैट्रिक्स मासिक रिपोर्ट को चलाने के लिए आया ... और जैसा कि आप कल्पना कर सकते हैं, यह समय समाप्त हो गया है!

प्रो कॉल बहुत सरल था - 3 पैरामीटर। एक प्रारंभ तिथि, समाप्ति तिथि, और एक जिला फ़िल्टर करने के लिए - शून्य सभी के बराबर है। 2 तारीखों को क्रिस्टल रिपोर्ट्स से एक चरित्र के रूप में पारित किया गया था और इन संग्रहीत प्रोसी पैरामीटर को इस पागल संग्रहित प्रो में पूरे स्थान पर उपयोग किया जाता था।

17 पंक्तियों में से प्रत्येक - मूल रूप से परिणामों में गिनती/पिवोट करने से पहले डेटा की पंक्तियों को खोजने के लिए बयानों और पागल जुड़ने के साथ उपयोग करता है ... जो इस आलेख में महत्वपूर्ण नहीं है।

तो यहाँ यह सरल है ....

CREATE PROCEDURE [dbo].[prcMonthlyStats] 
@bDate   datetime 
,@eDate   datetime 
,@districtStr varchar(120) 
AS 
BEGIN 
SET NOCOUNT ON; 

...

--the @bDate and @eDate params were DIRECTLY used throughout the 2000 lines of SQL, 
--to filter data inside and out of WITH statements and various other selects! 
-- 
--TIMES OUT! 

...

CREATE PROCEDURE [dbo].[prcMonthlyStats] 
@bDateStr  datetime 
,@eDateStr  datetime 
,@districtStr varchar(120) 
AS 
BEGIN 
SET NOCOUNT ON; 

--FIX! Declare 2 date time variables and simply assign the 2 date time parameters to them. 
DECLARE @bDate  datetime 
DECLARE @eDate  datetime 
DECLARE @district varchar(120) 

--SET THE VARIABLES FROM THE PARAMETERS PASSED IN! 
SET @bDate = @bDateStr 
SET @eDate = @eDateStr 
SET @district = @districtStr 
..... 

--PRESTO! The optimizer could once again use indexes as it should. 

तो कहानी का नैतिक है - अनुकूलक था अस्वीकृत डेटाटाइम का उपयोग करके अपनी बात करने में सक्षम।