Jeg vil stærkt anbefale, at du tjekker dette svar, jeg postede til "Hvordan tæller du forekomsterne af en forankret streng ved hjælp af PostgreSQL?" . Det valgte svar viste sig at være meget langsommere end en tilpasset version af regexp_replace()
. Overheaden ved at oprette rækkerne og køre aggregatet er simpelthen for høj.
Den hurtigste måde at gøre dette på er som følger...
SELECT
(length(str) - length(replace(str, replacestr, '')) )::int
/ length(replacestr)
FROM ( VALUES
('foobarbaz', 'ba')
) AS t(str, replacestr);
Her er vi
- Tag længden af strengen,
L1
- Træk fra
L1
længden af strengen med alle erstatningerne fjernetL2
for at fåL3
forskellen i strenglængde. - Opdel
L3
efter længden af udskiftningen for at få forekomsterne
Til sammenligning er det cirka fem gange hurtigere end metoden til at bruge regexp_matches()
som ser sådan ud.
SELECT count(*)
FROM ( VALUES
('foobarbaz', 'ba')
) AS t(str, replacestr)
CROSS JOIN LATERAL regexp_matches(str, replacestr, 'g');