मेरे पास 1.5M पंक्तियों वाली एक अपेक्षाकृत सरल क्वेरी है:
SELECT mtid FROM publication
WHERE mtid IN (9762715) OR last_modifier=21321
LIMIT 5000;
EXPLAIN ANALYZE
उत्पादन:
Limit (cost=8.84..12.86 rows=1 width=8) (actual time=0.985..0.986 rows=1 loops=1) -> Bitmap Heap Scan on publication (cost=8.84..12.86 rows=1 width=8) (actual time=0.984..0.985 rows=1 loops=1) Recheck Cond: ((mtid = 9762715) OR (last_modifier = 21321)) -> BitmapOr (cost=8.84..8.84 rows=1 width=0) (actual time=0.971..0.971 rows=0 loops=1) -> Bitmap Index Scan on publication_pkey (cost=0.00..4.42 rows=1 width=0) (actual time=0.295..0.295 rows=1 loops=1) Index Cond: (mtid = 9762715) -> Bitmap Index Scan on publication_last_modifier_btree (cost=0.00..4.42 rows=1 width=0) (actual time=0.674..0.674 rows=0 loops=1) Index Cond: (last_modifier = 21321) Total runtime: 1.027 ms
अब तक बहुत अच्छा, तेज और उपलब्ध अनुक्रमित का उपयोग करता है।
अब, यदि मैं किसी क्वेरी को थोड़ा संशोधित करता हूं, तो परिणाम होगा:
SELECT mtid FROM publication
WHERE mtid IN (SELECT 9762715) OR last_modifier=21321
LIMIT 5000;
EXPLAIN ANALYZE
उत्पादन होता है:
Limit (cost=0.01..2347.74 rows=5000 width=8) (actual time=2735.891..2841.398 rows=1 loops=1) -> Seq Scan on publication (cost=0.01..349652.84 rows=744661 width=8) (actual time=2735.888..2841.393 rows=1 loops=1) Filter: ((hashed SubPlan 1) OR (last_modifier = 21321)) SubPlan 1 -> Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.001..0.001 rows=1 loops=1) Total runtime: 2841.442 ms
इतनी जल्दी नहीं, और seq स्कैन का उपयोग कर ...
बेशक, एप्लिकेशन द्वारा चलाई गई मूल क्वेरी थोड़ी अधिक जटिल है, और यहां तक कि धीमी भी है, और निश्चित रूप से हाइबरनेट-जनित मूल नहीं है (SELECT 9762715)
, लेकिन धीमेपन के लिए भी है (SELECT 9762715)
! हाइबरनेट द्वारा क्वेरी उत्पन्न की जाती है, इसलिए उन्हें बदलना एक चुनौती है, और कुछ सुविधाएँ उपलब्ध नहीं हैं (जैसे UNION
उपलब्ध नहीं है, जो कि तेज़ होगा)।
प्रश्न
- दूसरे मामले में सूचकांक का उपयोग क्यों नहीं किया जा सकता है? उनका उपयोग कैसे किया जा सकता है?
- क्या मैं किसी अन्य तरीके से क्वेरी के प्रदर्शन में सुधार कर सकता हूं?
अतिरिक्त विचार
ऐसा लगता है कि हम पहले मामले का चयन मैन्युअल रूप से एक SELECT करके कर सकते हैं, और फिर परिणामी सूची को क्वेरी में डाल सकते हैं। IN () सूची में 5000 नंबर के साथ भी यह दूसरे समाधान से चार गुना तेज है। हालांकि, यह सिर्फ गलत लगता है (भी, यह 100 गुना तेज हो सकता है :))। यह पूरी तरह से समझ में नहीं आता है कि क्वेरी प्लानर इन दो प्रश्नों के लिए पूरी तरह से अलग तरीके का उपयोग क्यों करता है, इसलिए मैं इस समस्या का एक अच्छा समाधान खोजना चाहता हूं।
(SELECT 9762715)
।
(SELECT 9762715)
। हाइबरनेट प्रश्न के लिए: यह किया जा सकता है, लेकिन इसके लिए गंभीर कोड रीराइट की आवश्यकता होती है, क्योंकि हमारे पास उपयोगकर्ता-परिभाषित हाइबरनेट मानदंड हैं जो ऑन-द-फ्लाई अनुवादित हैं। इसलिए अनिवार्य रूप से हम हाइबरनेट को संशोधित करेंगे जो कि बहुत सारे संभावित दुष्प्रभावों के साथ एक बड़ा उपक्रम है।
JOIN
इसके बजाय उत्पन्न होIN ()
? इसके अलावा,publication
हाल ही में विश्लेषण किया गया है?