2010-03-08 17 views
11

के अंदर 1000 से अधिक वस्तुओं का उपयोग कैसे करें मेरे पास एक SQL कथन है जहां मैं IN क्लॉज का उपयोग करके 1200 ep_codes का डेटा प्राप्त करना चाहता हूं। जब मैं इन क्लॉज के अंदर 1000 से अधिक ep_codes शामिल करता हूं, तो ओरेकल का कहना है कि मुझे ऐसा करने की अनुमति नहीं है। इस पर काबू पाने के लिए, मैं इस प्रकार SQL कोड को बदलने की कोशिश:ओरेकल एसक्यूएल: आईएन क्लॉज

SELECT period, ... 
FROM my_view 
WHERE period = '200912' 
     ... 
     AND ep_codes IN (...1000 ep_codes...) 
     OR ep_codes IN (...200 ep_codes...) 

कोड सफलतापूर्वक मार डाला गया था लेकिन परिणाम अजीब हैं (गणना परिणाम सभी अवधि के लिए लाई जाती हैं, बस 200,912 के लिए नहीं है, जो मैं क्या नहीं है चाहते हैं)। क्या ORIN क्लॉज के बीच ऐसा करने के लिए उचित है या क्या मुझे 1000 के साथ दो अलग-अलग कोड निष्पादित करना चाहिए और दूसरा 200 ep_codes के साथ?


पास्कल मार्टिन का समाधान पूरी तरह से काम करता है। उन सभी को धन्यवाद जिन्होंने मूल्यवान सुझावों के साथ योगदान दिया।

उत्तर

16

यह सुनिश्चित नहीं है कि IN() में इतने सारे मानों का उपयोग करना अच्छा है, वास्तव में - खासकर प्रदर्शन के लिए।

जब आप कहते हैं कि "परिणाम अजीब" हैं, तो शायद यह है क्योंकि ब्रांड्स के साथ समस्या है? क्या होगा अगर आप इस कोशिश के बजाय आप क्या प्रस्तावित की:

SELECT ... 
FROM ... 
WHERE ... 
     AND (
      ep_codes IN (...1000 ep_codes...) 
      OR ep_codes IN (...200 ep_codes...) 
    ) 

यह परिणाम कम अजीब बनाने करता है?

+0

मैं सवाल बातें अजीब परिणामों के बारे में स्पष्ट करना नवीनीकृत किया है। अब मैं आपके द्वारा प्रस्तावित कोड की कोशिश कर रहा हूं (अतिरिक्त कोष्ठक के साथ)। जैसे ही परिणाम प्राप्त किए जाते हैं, मैं आपको बता दूंगा। –

+0

धन्यवाद, यह अभी ठीक काम करता है। एक बार फिर मैं देखता हूं कि अतिरिक्त कोष्ठक कितने महत्वपूर्ण हैं। –

+0

आपका स्वागत है :-) - हाँ, कंस्ट्रैसिस सहायक हो सकता है ;-) –

25

ओरेकल में इसे संभालने का अनुशंसित तरीका एक अस्थायी तालिका बनाना है, इसमें मूल्य लिखना है, और फिर इसमें शामिल होना है। गतिशील रूप से बनाए गए IN क्लॉज का उपयोग करना मतलब है कि क्वेरी ऑप्टिमाइज़र प्रत्येक क्वेरी का 'हार्ड पार्स' करता है।

create global temporary table LOOKUP 
(
    ID NUMBER 
) on commit delete rows; 

-- Do a batch insert from your application to populate this table 
insert into lookup(id) values (?) 

-- join to it 
select foo from bar where code in (select id from lookup) 
+2

हमने हाल ही में एक अस्थायी लुकअप तालिका का उपयोग करने के लिए "इन" का उपयोग करने से कुछ कोड बदल दिया है। कुछ प्रश्नों के लिए प्रदर्शन ने नाटकीय रूप से एक मिनट के भीतर कई मिनट लेने में नाटकीय रूप से वृद्धि की। – Rene

+1

लेकिन क्या यह सर्वर के एकाधिक समानांतर अनुरोधों के लिए एक वैध कार्यान्वयन है? जहां तक ​​मैं समझता हूं कि ओरेकल सर्वर पर कई खुले लेनदेन हो सकते हैं, 'लुकअप' तालिका –

+0

@Ilya बनाने की कोशिश कर रहे हैं: http://stackoverflow.com/questions/8240810/when-will-data-in-oracle- सत्र देखें -temporary-टेबल मिल हटाए।"प्रतिबद्धता पंक्तियों को हटाने" के साथ, डेटा केवल लेनदेन के दायरे में दिखाई देना चाहिए। – shelley

1

ऐसा लगता है कि कोड को एक अलग तालिका में रखने के लिए प्रदर्शन और रखरखाव दोनों के लिए एक बेहतर विचार होगा।

SELECT ... 
FROM ... 
WHERE ... 
    AND ep_code in (select code from ep_code_table) 
0

आप एक अस्थायी तालिका में 1200 ep_code मूल्यों डाल सकता है और उसके बाद INNER JOIN कि मेज पर पंक्तियों को फ़िल्टर करने के बजाय?

SELECT a.* 
FROM mytable a 
INNER JOIN tmp ON (tmp.ep_code = a.ep_code) 
WHERE ... 
+0

मुझे इसके बारे में निश्चित नहीं है। मैं कुछ विचारों का उपयोग कर रहा हूं जो आईटी ने मेरे लिए प्रदान की है। –

6

दरअसल आप यहां संग्रह/मल्टीसेट का उपयोग कर सकते हैं। उन्हें स्टोर करने के लिए आपको एक संख्या तालिका प्रकार की आवश्यकता होगी।

CREATE TYPE NUMBER_TABLE AS TABLE OF NUMBER; 
... 
SELECT * 
FROM my_view 
WHERE period MEMBER OF NUMBER_TABLE(1,2,3...10000) 

multisets here के बारे में और अधिक पढ़ें:

+0

यह बहुत ही सुरुचिपूर्ण वाक्य रचनात्मक है लेकिन प्रदर्शन निराशाजनक है। एक प्राथमिक प्राथमिक मूल्य का चयन करने के लिए इस वाक्यविन्यास का उपयोग करना सीबीओ एक इंडेक्स फास्ट फुल स्कैन चुनता है। –

+0

कुछ हज़ार आईडी और एक मध्यम आकार की तालिका (40 के पंक्तियों) के साथ परीक्षण, यह अभी भी एक temp तालिका (हैश शामिल होने के कारण) में शामिल होने से लगभग 3x तेज है। यह अस्थायी तालिका बनाने और पॉप्युलेट करने के लिए समय की गणना नहीं कर रहा है। –

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