与子查询一起使用时,为什么"IN"运算符这么慢?
select *
from view1
where id in (1,2,3,4,5,6,7,8,9,10)
order by somedata;
Run Code Online (Sandbox Code Playgroud)
在9ms内执行.
select *
from view1
where id in (select ext_id
from aggregate_table
order by somedata limit 10)
order by somedata;
Run Code Online (Sandbox Code Playgroud)
在25000ms内执行并且似乎在view(view1)上使用顺序扫描,而不是像在第一个查询中那样在子查询返回的主键上使用索引扫描.
子查询select ext_id from aggregate_table order by somedata limit 10在0.1ms内执行
所以第二个查询的缓慢是由顺序扫描引起的,在view1该扫描中,每个UNION中包含三个UNIONS和大约三个JOINS的视图.第一个UNION包含大约1M行,其他更少.连接有大约100K行的表.但这并不是那么相关,我只想了解IN运算符的行为.
我想要完成的是获取子查询(一组主键)的结果,并view1使用它们从复杂视图()中选择数据.
我也不能用
select v1.*
from view1 v1,
aggregate_table at
where v1.id = at.ext_id
order by at.somedata
limit 10
Run Code Online (Sandbox Code Playgroud)
因为我不想对大联盟进行排序somedata.我只想从主键视图中选择10个结果,然后只对它们进行排序.
问题是为什么当我明确列出这些键时IN运算符执行速度很快,而当我使用返回完全相同的键集的快速子查询时速度很慢?
根据要求解析分析
第一个查询 - select * from view1 …
在引发异常时是否可以创建自定义条件?请考虑以下示例:
BEGIN
y := x / 0;
EXCEPTION
WHEN division_by_zero THEN
RAISE NOTICE 'caught division_by_zero';
RETURN x;
END;
Run Code Online (Sandbox Code Playgroud)
在这里,我使用'division_by_zero'条件来捕获异常.我想做的是这样的事情:
BEGIN
[...]
RAISE custom_condition;
EXCEPTION
WHEN custom_condition THEN
[...]
END;
Run Code Online (Sandbox Code Playgroud)
这样我就不会干扰可能的标准异常.我可以做y:= 1/0; 并抓住division_by_zero,但它看起来并不正确.
postgresql exception-handling exception custom-exceptions conditional-statements