जैसा कि @Milen ने पहले ही regexp_matches()
mentioned का उल्लेख किया है शायद आपके उद्देश्य के लिए गलत कार्य है। आप एक आसान रेगुलर एक्सप्रेशन मैच चाहते हैं (~
)
. दरअसल, LIKE ऑपरेटर (~~
)
तेज़होगा :
संभवतः LIKE के साथ सबसे तेज़
SELECT msg.message
,msg.src_addr
,msg.dst_addr
,mnc.name
FROM mnc
JOIN msg ON msg.src_addr ~~ ('%38' || mnc.code || '%')
OR msg.dst_addr ~~ ('%38' || mnc.code || '%')
WHERE length(mnc.code) = 3
इसके अलावा, आप केवल mnc.code
want चाहते हैं बिल्कुल 3 वर्णों में से।
regexp के साथ
आप कर सकते थे इसे नियमित अभिव्यक्तियों के साथ लिखें लेकिन यह निश्चित रूप से धीमा होगा। यहां आपके मूल के करीब एक कार्यशील उदाहरण दिया गया है:
SELECT msg.message
,msg.src_addr
,msg.dst_addr
,mnc.name
FROM mnc
JOIN msg ON (msg.src_addr || '+' || msg.dst_addr) ~ (38 || mnc.code)
AND length(mnc.code) = 3
इसके लिए msg.src_addr
की भी आवश्यकता होती है और msg.dst_addr
होने के लिए NOT NULL
।
दूसरी क्वेरी दर्शाती है कि कैसे अतिरिक्त जाँच length(mnc.code) = 3
JOIN
में जा सकते हैं शर्त या WHERE
खंड। यहाँ वही प्रभाव।
regexp_matches() के साथ
आप कर सकते थे यह काम regexp_matches()
के साथ करें
:
SELECT msg.message
,msg.src_addr
,msg.dst_addr
,mnc.name
FROM mnc
JOIN msg ON EXISTS (
SELECT *
FROM regexp_matches(msg.src_addr ||'+'|| msg.dst_addr, '38(...)', 'g') x(y)
WHERE y[1] = mnc.code
)
लेकिन यह तुलना में धीमा होगा - या तो मुझे लगता है।
स्पष्टीकरण:
आपका regexp_matches() एक्सप्रेशन, पहले के सभी कैप्चर किए गए सबस्ट्रिंग की एक सरणी देता है मिलान। जैसा कि आप केवल एक सबस्ट्रिंग (आपके पैटर्न में ब्रैकेट की एक जोड़ी) को कैप्चर करते हैं, आपको विशेष रूप से एक तत्व के साथ सरणी प्राप्त होगी ।
आपको सभी मैच get मिलते हैं अतिरिक्त "विश्व स्तर पर" स्विच के साथ 'g'
- लेकिन कई पंक्तियों में। तो आपको उन सभी (या कुल) का परीक्षण करने के लिए उप-चयन की आवश्यकता है। इसे EXISTS
. में रखें - सेमी-जॉइन करें और आप जो चाहते हैं उस पर पहुंचें।
हो सकता है कि आप प्रदर्शन परीक्षण के साथ वापस रिपोर्ट कर सकें तीनों में से? व्याख्या विश्लेषण का उपयोग करें उसके लिए।