Gorąco sugeruję zapoznanie się z odpowiedzią, którą wysłałem do „Jak zliczać wystąpienia zakotwiczonego ciągu znaków za pomocą PostgreSQL?” . Wybrana odpowiedź okazała się być znacznie wolniejsza niż dostosowana wersja regexp_replace() . Narzut związany z tworzeniem rzędów i uruchamianiem agregatu jest po prostu zbyt wysoki.
Najszybszy sposób, aby to zrobić, jest następujący...
SELECT
(length(str) - length(replace(str, replacestr, '')) )::int
/ length(replacestr)
FROM ( VALUES
('foobarbaz', 'ba')
) AS t(str, replacestr);
Tutaj
- Weź długość ciągu,
L1 - Odejmij od
L1długość ciągu z usuniętymi wszystkimi zamiennikamiL2aby uzyskaćL3różnica w długości łańcucha. - Podziel
L3o długość zamiany, aby uzyskać wystąpienia
Dla porównania to około pięć razy szybciej niż metoda użycia regexp_matches() który wygląda tak.
SELECT count(*)
FROM ( VALUES
('foobarbaz', 'ba')
) AS t(str, replacestr)
CROSS JOIN LATERAL regexp_matches(str, replacestr, 'g');