postgresql(version 1.18.1) create index on join table/ or the way below is nested query
i have two table here:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
role TEXT NOT NULL,
age INTEGER NOT NULL,
state TEXT NOT NULL
);
CREATE TABLE sales (
id SERIAL PRIMARY KEY,
uid INTEGER REFERENCES users (id) ON DELETE CASCADE,
pid INTEGER REFERENCES products (id) ON DELETE CASCADE,
quantity INTEGER NOT NULL,
price INTEGER NOT NULL
);
right now i have the query to compute one state customer total sales
select COALESCE(sum(quantity*price),0) as bigsum
from sales, users where users.role='customer' and users.id=sales.uid
and state='New York'
"Aggregate (cost=326562.33..326562.34 rows=1 width=8)"
" -> Hash Join (cost=9927.33..325582.33 rows=196000 width=8)"
" Hash Cond: (sales.uid = users.id)"
" -> Seq Scan on sales (cost=0.00..163695.00 rows=10000000 width=12)"
" -> Hash (cost=9682.33..9682.33 rows=19600 width=4)"
" -> Bitmap Heap Scan on users (cost=424.32..9682.33 rows=19600 width=4)"
" Recheck Cond: (state = 'New York'::text)"
" Filter: (role = 'customer'::text)"
" -> Bitmap Index Scan on index_user_state (cost=0.00..419.43 rows=19600 width=0)"
" Index Cond: (state = 'New York'::text)"
where this give me 7940 ms. right now the sales table 10 million entries and users table 1000,000 entries i want it faster, how to do this? the index right now i have:
CREATE INDEX index_sales_user ON sales (uid);
CREATE INDEX index_user_id ON users (id);
CREATE INDEX index_user_role_state ON users(role) WHERE role = 'customer';
CREATE INDEX index_user_state ON users (state);
CREATE INDEX index_users_role ON users (role) where role='customer';
i got the result Total query runtime: 7334 ms. 1 row retrieved.
select COALESCE(sum(quantity*price),0) as bigsum
from sales where uid in (select id from users where role='customer' and state='New York')
"Aggregate (cost=217188.73..217188.74 rows=1 width=8)"
" -> Hash Semi Join (cost=9927.33..216033.22 rows=231101 width=8)"
" Hash Cond: (sales.uid = users.id)"
" -> Seq Scan on sales (cost=0.00..163695.00 rows=10000000 width=12)"
" -> Hash (cost=9682.33..9682.33 rows=19600 width=4)"
" -> Bitmap Heap Scan on users (cost=424.32..9682.33 rows=19600 width=4)"
" Recheck Cond: (state = 'New York'::text)"
" Filter: (role = 'customer'::text)"
" -> Bitmap Index Scan on index_user_state (cost=0.00..419.43 rows=19600 width=0)"
" Index Cond: (state = 'New York'::text)"
explain analyze
results, etc. – Craig Ringer May 31 at 5:53-> Seq Scan on sales (cost=0.00..163695.00 rows=10000000 width=12)
The plan generator is assuming an almost catesian product here; did you runVACUUM analyze users; VACUUM ANALYZE sales;
after creting the indexes ? BTW(stylistic) : 1) use JOIN syntax 2) user aliases 3) replacex.a IN (select b... from y)
byEXISTS (select 1 from y where y.b = x.a ...)
` – wildplasser May 31 at 12:40