मैं माइक्रोसॉफ्ट एसक्यूएल सर्वर 2008 (एसपी 1, एक्स 64) का उपयोग करता हूं। मेरे पास दो प्रश्न हैं जो वही करते हैं, या इसलिए मुझे लगता है, लेकिन उनके पास पूरी तरह से अलग-अलग क्वेरी योजनाएं और प्रदर्शन हैं।OR का उपयोग कर इन टी-एसक्यूएल प्रश्नों के बीच क्या अंतर है?
क्वेरी 1:
SELECT c_pk
FROM table_c
WHERE c_b_id IN (SELECT b_id FROM table_b WHERE b_z = 1)
OR c_a_id IN (SELECT a_id FROM table_a WHERE a_z = 1)
क्वेरी 2:
SELECT c_pk
FROM table_c
LEFT JOIN (SELECT b_id FROM table_b WHERE b_z = 1) AS b ON c_b_id = b_id
LEFT JOIN (SELECT a_id FROM table_a WHERE a_z = 1) AS a ON c_a_id = a_id
WHERE b_id IS NOT NULL
OR a_id IS NOT NULL
क्वेरी 1 जबकि क्वेरी 2 बहुत धीमी है, जैसा कि मैंने उम्मीद करेंगे तेज है। query plans काफी अलग दिखता है।
मैं क्वेरी 2 को क्वेरी 1 के रूप में तेज़ करना चाहता हूं। मेरे पास सॉफ़्टवेयर है जो क्वेरी 2 का उपयोग करता है, और मैं इसे क्वेरी 1 में नहीं बदल सकता। मैं डेटाबेस बदल सकता हूं।
कुछ सवाल:
- क्यों क्वेरी अलग योजना बना रही है कर रहे हैं?
- क्या मैं SQL सर्वर को "सिखा सकता हूं" कि क्वेरी 2 क्वेरी 1 के बराबर है?
सभी तालिकाओं (क्लस्टर) है प्राथमिक कुंजी और उचित अनुक्रमित सभी स्तंभों पर:
CREATE TABLE table_a (
a_pk int NOT NULL PRIMARY KEY,
a_id int NOT NULL UNIQUE,
a_z int
)
GO
CREATE INDEX IX_table_a_z ON table_a (a_z)
GO
CREATE TABLE table_b (
b_pk int NOT NULL PRIMARY KEY,
b_id int NOT NULL UNIQUE,
b_z int
)
GO
CREATE INDEX IX_table_b_z ON table_b (b_z)
GO
CREATE TABLE table_c (
c_pk int NOT NULL PRIMARY KEY,
c_a_id int,
c_b_id int
)
GO
CREATE INDEX IX_table_c_a_id ON table_c (c_a_id)
GO
CREATE INDEX IX_table_c_b_id ON table_c (c_b_id)
GO
टेबल शुरू में भरने के बाद संशोधित नहीं कर रहे हैं। मैं केवल उनसे पूछताछ कर रहा हूं। उनमें लाखों रिकॉर्ड हैं (table_a: 5M, table_b: 4M, table_c: 12M), लेकिन केवल 1% का उपयोग करने से समान परिणाम मिलते हैं।
संपादित करें: मैं c_a_id
और c_b_id
के लिए विदेशी कुंजी जोड़ने की कोशिश की है, लेकिन मुझे आशा है कि केवल बनाया क्वेरी 1 धीमी ...
किसी query plans पर एक नजर है और अंतर की व्याख्या कर सकते हैं।
इसके लिए प्रेरणा क्या है? 'IN/EXISTS' आमतौर पर SQL सर्वर में 'बाहरी जॉइन ... NULL' से अधिक कुशल है और पहली क्वेरी मेरे लिए स्पष्ट प्रतीत होती है तो क्यों न केवल पहले का उपयोग करें? –
@ मार्टिन "मेरे पास सॉफ़्टवेयर है जो क्वेरी 2 का उपयोग करता है, और मैं इसे बदल नहीं सकता" –
सामान्य रूप से प्रश्न समान नहीं होते हैं क्योंकि जॉइन डुप्लिकेट पंक्तियों में ला सकता है जबकि अर्द्ध शामिल नहीं होता है। यद्यपि आपने जांच नहीं की है, यदि आपके पास कोई बाधा है जो अभी तक इसे रोकती है। –