我有两个查询,一个是使用 OR 表达式并且运行速度非常快。另一个查询类似但是使用 IN 表达式而不是 OR 并且运行速度非常慢。如果您能够使用 IN 和使用 OR 一样快速地告诉我如何使用 IN ,我将不胜感激。该表有1500万条记录
SELECT e.id
FROM events e,
resources r
WHERE e.resource_id = r.id
AND resource_type_id IN (19872817,
282)
ORDER BY occurrence_date DESC LIMIT 100
Limit (cost=0.85..228363.80 rows=100 width=12) (actual time=238.668..57470.017 rows=19 loops=1)
-> Nested Loop (cost=0.85..26211499.28 rows=11478 width=12) (actual time=238.667..57470.010 rows=19 loops=1)
Join Filter: (e.resource_id = r.id)
Rows Removed by Join Filter: 507548495
-> Index Scan using eventoccurrencedateindex on events e (cost=0.43..603333.83 rows=15380258 width=16) (actual time=0.023..2798.538 rows=15380258 loops=1)
-> Materialize (cost=0.42..36.16 rows=111 width=4) (actual time=0.000..0.001 rows=33 loops=15380258)
-> Index Scan using resources_type_fk_index on resources r (cost=0.42..35.60 rows=111 width=4) (actual time=0.014..0.107 rows=33 loops=1)
Index Cond: (resource_type_id = ANY ('{19872817,282}'::integer[]))
Total runtime: 57470.057 ms
SELECT e.id
FROM events e,
resources r
WHERE e.resource_id = r.id
AND (resource_type_id = '19872817' OR resource_type_id = '282')
ORDER BY occurrence_date DESC LIMIT 100
Limit (cost=10.17..14.22 rows=100 width=12) (actual time=0.060..0.181 rows=100 loops=1)
-> Nested Loop (cost=10.17..34747856.23 rows=858030913 width=12) (actual time=0.059..0.167 rows=100 loops=1)
Join Filter: (((e.resource_id = r.id) AND (r.resource_type_id = 19872817)) OR (r.resource_type_id = 282))
-> Index Scan using eventoccurrencedateindex on events e (cost=0.43..603333.83 rows=15380258 width=16) (actual time=0.018..0.019 rows=4 loops=1)
-> Materialize (cost=9.74..349.92 rows=111 width=8) (actual time=0.009..0.023 rows=25
loops=4)
-> Bitmap Heap Scan on resources r (cost=9.74..349.36 rows=111 width=8) (actual time=0.034..0.081 rows=33 loops=1)
Recheck Cond: ((resource_type_id = 19872817) OR (resource_type_id = 282))
-> BitmapOr (cost=9.74..9.74 rows=111 width=0) (actual time=0.023..0.023 rows=0 loops=1)
-> Bitmap Index Scan on resources_type_fk_index (cost=0.00..4.84 rows=56 width=0) (actual time=0.009..0.009 rows=0 loops=1)
Index Cond: (resource_type_id = 19872817)
-> Bitmap Index Scan on resources_type_fk_index (cost=0.00..4.84 rows=56 width=0) (actual time=0.014..0.014 rows=33 loops=1)
Index Cond: (resource_type_id = 282)" "Total runtime: 0.242 ms
答案 0 :(得分:1)
这在or
版本中很奇怪:
Join Filter: (
((e.resource_id = r.id) AND (r.resource_type_id = 19872817))
OR
(r.resource_type_id = 282)
)
首先e.resource_id = r.id AND r.resource_type_id = 19872817
然后OR r.resource_type_id = 282
这是错误的。您确定在该查询中发出了正确的条件吗?请注意,必须有括号OR
:
e.resource_id = r.id
AND
(r.resource_type_id = 19872817 OR r.resource_type_id = 282)