我的应用程序中有2个表
独特的提醒
asset_id (primary key)
current_price
警报
id (primary key)
userid
asset_id (may appear more than once)
alert_price
direction (contains true or false)
我的警报表有100万行,独特的警报表有40000行,我希望找到所有触发的警报
select * from unique_alerts u
INNER JOIN alerts a
ON u.asset_id=a.asset_id
WHERE u.current_price > a.alert_price
AND a.direction=true
OR u.current_price <= a.alert_price
AND a.direction=false
当我对这个查询运行解析分析时,我看到2个顺序扫描,我在a.asset_id上定义了一个索引,它没有被使用
"Hash Join (cost=1248.49..34977.79 rows=270686 width=72) (actual time=37.698..713.334 rows=21825 loops=1)"
" Hash Cond: ((a.pair)::text = (u._id)::text)"
" Join Filter: (((u.current_price > a.alert_price) AND a.direction) OR ((u.current_price <= a.alert_price) AND (NOT a.direction)))"
" Rows Removed by Join Filter: 857192"
" -> Seq Scan on alerts a (cost=0.00..20490.00 rows=751170 width=52) (actual time=0.014..158.984 rows=1000000 loops=1)"
" Filter: (direction OR (NOT direction))"
" -> Hash (cost=711.55..711.55 rows=42955 width=20) (actual time=37.528..37.528 rows=42955 loops=1)"
" Buckets: 65536 Batches: 1 Memory Usage: 2766kB"
" -> Seq Scan on unique_alerts u (cost=0.00..711.55 rows=42955 width=20) (actual time=0.007..4.891 rows=42955 loops=1)"
"Planning time: 0.781 ms"
"Execution time: 714.892 ms"
我如何确保使用索引a.asset_id以及我需要哪些索引?此外,如果我必须多次运行此连接,视图会更好吗?谢谢
OR
可能会让优化者感到困难。
一种选择是使用UNION ALL
来允许两个查询计划......
SELECT * FROM unique_alerts u
INNER JOIN alerts a
ON u.asset_id=a.asset_id
WHERE u.current_price > a.alert_price AND a.direction=true
UNION ALL
SELECT * FROM unique_alerts u
INNER JOIN alerts a
ON u.asset_id=a.asset_id
WHERE u.current_price <= a.alert_price AND a.direction=false
如果您打算这样做,我会建议在alerts
上使用复合索引:(direction, asset_id, alert_price)
这样的索引可以更容易地缩小适当的行范围。