postgresql(版本1.18.1) 在连接表上创建索引/或下面的方式是嵌套查询
我在这里有两张桌子:
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
);
现在我有查询来计算一个州的客户总销售额
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)"
这给我7940毫秒。 现在销售表1000万条目和用户表1000,000条目 我想要更快,怎么做? 我现在的指数是:
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';
我得到了结果 总查询运行时间:7334毫秒。 检索到1行。
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)"