Som @Milen allerede nævnte regexp_matches()
er sandsynligvis den forkerte funktion til dit formål. Du vil have et simpelt match med regulære udtryk (~
)
. Faktisk er LIKE-operatoren (~~
)
vil være hurtigere :
Formodentlig hurtigst med 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
Derudover vil du kun have mnc.code
på præcis 3 tegn.
Med regexp
Du kunne skriv det samme med regulære udtryk, men det vil helt sikkert være langsommere. Her er et fungerende eksempel tæt på din original:
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
Dette kræver også msg.src_addr
og msg.dst_addr
at være NOT NULL
.
Den anden forespørgsel viser, hvordan den ekstra check length(mnc.code) = 3
kan gå ind i JOIN
betingelse eller en WHERE
klausul. Samme effekt her.
Med regexp_matches()
Du kunne få dette til at fungere med 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
)
Men det vil gå langsomt i sammenligning - eller det går jeg ud fra.
Forklaring:
Dit regexp_matches() udtryk returnerer bare en matrix af alle optagne understrenge af den første match. Da du kun fanger én understreng (et par parenteser i dit mønster), vil du udelukkende få arrays med ét element .
Du får alle match med den ekstra "globalt" kontakt 'g'
- men i flere rækker. Så du har brug for et undervalg for at teste dem alle (eller samlet). Indsæt det i en EXISTS
- semi-join og du når frem til det du ønskede.
Måske kan du melde tilbage med en præstationstest af alle tre? Brug EXPLAIN ANALYZE for det.