-
Notifications
You must be signed in to change notification settings - Fork 643
Commit 638f37a
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 files changed
+4
-0
lines changedmigrations/2019-05-14-165316_index_crate_name_for_like/down.sql
Copy file name to clipboard+2
Original file line number | Diff line number | Diff line change | |
---|---|---|---|
| |||
| 1 | + | |
| 2 | + |
migrations/2019-05-14-165316_index_crate_name_for_like/up.sql
Copy file name to clipboard+2
Original file line number | Diff line number | Diff line change | |
---|---|---|---|
| |||
| 1 | + | |
| 2 | + |
0 commit comments