Skip to content

Commit 638f37a

Browse files
committed
Auto merge of #1746 - sgrif:sg-index-crate-name, r=jtgeibel
Fix performance regression on crate search A major performance regression was introduced by #1560, as it didn't introduce the appropriate index and the query is now falling back to a sequential scan. This has caused the query to increase from 12ms on average to 756ms on average. This introduces the appropriate index, bringing performance back to its previous levels. Original Query --- ``` QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Limit (cost=180.26..180.26 rows=1 width=881) (actual time=0.509..0.509 rows=0 loops=1) -> WindowAgg (cost=180.26..180.26 rows=1 width=881) (actual time=0.508..0.508 rows=0 loops=1) -> Sort (cost=180.26..180.26 rows=1 width=873) (actual time=0.506..0.506 rows=0 loops=1) Sort Key: ((replace(lower((crates.name)::text), '-'::text, '_'::text) = 'crates_io_test'::text)) DESC, crates.name Sort Method: quicksort Memory: 25kB -> Nested Loop Left Join (cost=174.19..180.25 rows=1 width=873) (actual time=0.502..0.502 rows=0 loops=1) -> Bitmap Heap Scan on crates (cost=174.13..176.19 rows=1 width=864) (actual time=0.502..0.502 rows=0 loops=1) Recheck Cond: ((plainto_tsquery('crates-io-test'::text) @@ textsearchable_index_col) OR (replace(lower((name)::text), '-'::text, '_'::text) = 'crates_io_test'::text)) -> BitmapOr (cost=174.13..174.13 rows=1 width=0) (actual time=0.500..0.500 rows=0 loops=1) -> Bitmap Index Scan on index_crates_name_search (cost=0.00..172.05 rows=1 width=0) (actual time=0.475..0.475 rows=0 loops=1) Index Cond: (plainto_tsquery('crates-io-test'::text) @@ textsearchable_index_col) -> Bitmap Index Scan on index_crates_name (cost=0.00..2.08 rows=1 width=0) (actual time=0.025..0.025 rows=0 loops=1) Index Cond: (replace(lower((name)::text), '-'::text, '_'::text) = 'crates_io_test'::text) -> Index Scan using recent_crate_downloads_crate_id on recent_crate_downloads (cost=0.06..4.06 rows=1 width=12) (never executed) Index Cond: (crate_id = crates.id) Planning Time: 0.658 ms Execution Time: 0.565 ms ``` New Query w/o this commit --- ``` QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Limit (cost=4614.84..4614.86 rows=3 width=881) (actual time=225.720..225.720 rows=0 loops=1) -> WindowAgg (cost=4614.84..4614.86 rows=3 width=881) (actual time=225.719..225.719 rows=0 loops=1) -> Sort (cost=4614.84..4614.84 rows=3 width=873) (actual time=225.717..225.717 rows=0 loops=1) Sort Key: ((replace(lower((crates.name)::text), '-'::text, '_'::text) = 'crates_io_test'::text)) DESC, crates.name Sort Method: quicksort Memory: 25kB -> Nested Loop Left Join (cost=0.06..4614.84 rows=3 width=873) (actual time=225.710..225.711 rows=0 loops=1) -> Seq Scan on crates (cost=0.00..4602.65 rows=3 width=864) (actual time=225.709..225.709 rows=0 loops=1) Filter: ((plainto_tsquery('crates-io-test'::text) @@ textsearchable_index_col) OR (replace(lower((name)::text), '-'::text, '_'::text) ~~ 'crates_io_test'::text)) Rows Removed by Filter: 25739 -> Index Scan using recent_crate_downloads_crate_id on recent_crate_downloads (cost=0.06..4.06 rows=1 width=12) (never executed) Index Cond: (crate_id = crates.id) Planning Time: 0.536 ms Execution Time: 225.774 ms ``` New Query after this commit ``` QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Limit (cost=80.32..80.34 rows=3 width=881) (actual time=0.466..0.466 rows=0 loops=1) -> WindowAgg (cost=80.32..80.34 rows=3 width=881) (actual time=0.465..0.465 rows=0 loops=1) -> Sort (cost=80.32..80.32 rows=3 width=873) (actual time=0.464..0.464 rows=0 loops=1) Sort Key: ((replace(lower((crates.name)::text), '-'::text, '_'::text) = 'crates_io_test'::text)) DESC, crates.name Sort Method: quicksort Memory: 25kB -> Nested Loop Left Join (cost=62.11..80.32 rows=3 width=873) (actual time=0.459..0.459 rows=0 loops=1) -> Bitmap Heap Scan on crates (cost=62.05..68.13 rows=3 width=864) (actual time=0.458..0.458 rows=0 loops=1) Recheck Cond: ((plainto_tsquery('crates-io-test'::text) @@ textsearchable_index_col) OR (replace(lower((name)::text), '-'::text, '_'::text) ~~ 'crates_io_test'::text)) Rows Removed by Index Recheck: 22 Heap Blocks: exact=21 -> BitmapOr (cost=62.05..62.05 rows=3 width=0) (actual time=0.255..0.255 rows=0 loops=1) -> Bitmap Index Scan on index_crates_name_search (cost=0.00..28.05 rows=1 width=0) (actual time=0.103..0.103 rows=0 loops=1) Index Cond: (plainto_tsquery('crates-io-test'::text) @@ textsearchable_index_col) -> Bitmap Index Scan on sgrif_testing (cost=0.00..34.00 rows=3 width=0) (actual time=0.151..0.151 rows=22 loops=1) Index Cond: (replace(lower((name)::text), '-'::text, '_'::text) ~~ 'crates_io_test'::text) -> Index Scan using recent_crate_downloads_crate_id on recent_crate_downloads (cost=0.06..4.06 rows=1 width=12) (never executed) Index Cond: (crate_id = crates.id) Planning Time: 0.476 ms Execution Time: 0.528 ms ```
2 parents 79d4b1e + eccc699 commit 638f37a

File tree

2 files changed

+4
-0
lines changed

2 files changed

+4
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
DROP INDEX index_crates_name_tgrm;
2+
DROP EXTENSION pg_trgm;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CREATE EXTENSION pg_trgm;
2+
CREATE INDEX index_crates_name_tgrm ON crates USING gin (canon_crate_name(name) gin_trgm_ops);

0 commit comments

Comments
 (0)