I have a SQL export of a cloud-based Postgres DB that I've imported locally (Alpine PG 14.5 on Docker). I'm having an issue where a query returns two different results on each one (both are running 14.5). The remote machine has 7.5GB memory and 2 CPUs. Locally I'm running an M1 Macbook Pro with 32GB of memory.
The issue is execution speed. The local one completes on my test query in ~15ms, the cloud takes ~5000ms. the 'websites' column is JSONB with a gin index applied. I believe that the data/table structure in both DBs is completely identical given the export/import process. There are just over 1,000,000 records in the users table.
EXPLAIN SELECT "users".* FROM "users" WHERE "users"."group_id" = 1 AND (websites @> '[{"url":"test.com/route"}]' OR websites @> '[{"url":"site.com/place"}]' OR websites @> '[{"url":"other.com/location"}]') ORDER BY "users"."id" ASC LIMIT 1
This is the result on my local machine:
Limit (cost=1314.34..1314.34 rows=1 width=1188)
-> Sort (cost=1314.34..1315.10 rows=306 width=1188)
Sort Key: id
-> Bitmap Heap Scan on users (cost=122.53..1312.81 rows=306 width=1188)
Recheck Cond: ((profiles @> '[{\"url\": \"test.com/route\"}]'::jsonb) OR (profiles @> '[{\"url\": \"site.com/place\"}]'::jsonb) OR (profiles @> '[{\"url\": \"other.com/location\"}]'::jsonb))
Filter: (group_id = 1)
-> BitmapOr (cost=122.53..122.53 rows=306 width=0)
-> Bitmap Index Scan on index_users_on_profiles (cost=0.00..40.77 rows=102 width=0)
Index Cond: (profiles @> '[{\"url\": \"test.com/route\"}]'::jsonb)
-> Bitmap Index Scan on index_users_on_profiles (cost=0.00..40.77 rows=102 width=0)
Index Cond: (profiles @> '[{\"url\": \"site.com/place\"}]'::jsonb)
-> Bitmap Index Scan on index_users_on_profiles (cost=0.00..40.77 rows=102 width=0)
Index Cond: (profiles @> '[{\"url\": \"linkedin.com/in/haidar-khan-62a27251\"}]'::jsonb)
And this is the result from the remote server:
Limit (cost=0.43..3009.22 rows=1 width=1082)
-> Index Scan using users_pkey on users (cost=0.43..914673.14 rows=304 width=1082)
Filter: ((group_id = '1'::bigint) AND ((websites @> '[{"url": "test.com/route"}]'::jsonb) OR (websites @> '[{"url": "site.com/place"}]'::jsonb) OR (websites @> '[{"url": "other.com/location"}]'::jsonb)))
Any thought on settings, machine configurations, etc. that could be causing the strategies to differ?