Jak już wspomniał @Milen regexp_matches() jest prawdopodobnie niewłaściwą funkcją dla twojego celu. Potrzebujesz prostego regularnego dopasowania wyrażenia (~ )
. W rzeczywistości operator LIKE (~~ )
będzie szybciej :
Prawdopodobnie najszybszy dzięki 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
Ponadto potrzebujesz tylko mnc.code dokładnie 3 znaki.
Z wyrażeniem regularnym
możesz napisz to samo z wyrażeniami regularnymi, ale z pewnością będzie to wolniejsze. Oto działający przykład zbliżony do oryginału:
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
Wymaga to również msg.src_addr i msg.dst_addr być NOT NULL .
Drugie zapytanie pokazuje, jak dodatkowe sprawdzenie length(mnc.code) = 3 można przejść do JOIN warunek lub WHERE klauzula. Ten sam efekt tutaj.
Z regexp_matches()
możesz spraw, aby to działało z 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
)
Ale w porównaniu będzie to powolne - a przynajmniej tak zakładam.
Wyjaśnienie:
Twoje wyrażenie regexp_matches() po prostu zwraca tablicę wszystkich przechwyconych podciągów pierwszego mecz. Ponieważ przechwycisz tylko jeden podciąg (jedną parę nawiasów we wzorcu), otrzymasz wyłącznie tablice z jednym elementem .
Otrzymujesz wszystkie dopasowania z dodatkowym przełącznikiem „globalnie” 'g' - ale w wielu rzędach. Potrzebujesz więc podselekcji, aby przetestować je wszystkie (lub zagregować). Umieść to w EXISTS - pół-dołącz i osiągniesz to, czego chciałeś.
Może możesz zgłosić się z testem wydajności wszystkich trzech? Użyj WYJAŚNIJ ANALIZĘ za to.