Ric*_*ckL 12 sql sql-server oracle optimization
我正在尝试在Oracle中运行以下SQL语句,运行需要很长时间:
SELECT orderID FROM tasks WHERE orderID NOT IN
(SELECT DISTINCT orderID FROM tasks WHERE
engineer1 IS NOT NULL AND engineer2 IS NOT NULL)
Run Code Online (Sandbox Code Playgroud)
如果我只运行IN子句中的子部分,它在Oracle中运行得非常快,即
SELECT DISTINCT orderID FROM tasks WHERE
engineer1 IS NOT NULL AND engineer2 IS NOT NULL
Run Code Online (Sandbox Code Playgroud)
为什么整个声明在Oracle中需要这么长时间?在SQL Server中,整个语句运行得很快.
或者,我应该使用更简单/不同/更好的SQL语句吗?
关于这个问题的更多细节:
如果它有任何区别,表中有大约120k行,每个订单有3个任务,所以~40k不同的订单.
回答答案:
我想在原始的SQL语句中,每次为SQL语句的第一部分中的每一行运行子查询 - 即使它是静态的,只需要运行一次?
执行
ANALYZE TABLE tasks COMPUTE STATISTICS;
Run Code Online (Sandbox Code Playgroud)
使我原来的SQL语句执行得更快.
虽然我仍然很好奇为什么我必须这样做,如果/当我需要再次运行它?
统计信息为Oracle提供了确定不同执行计划效率所需的基于成本的优化器信息:例如,表中的行数,行的平均宽度,每列的最高值和最低值,每列的不同值的数量,索引的聚类因子等
在一个小型数据库中,您可以设置一个工作,以便每晚收集统计信息并将其置之不理.实际上,这是10g以下的默认值.对于较大的实现,您通常必须权衡执行计划的稳定性与数据更改的方式,这是一个棘手的平衡.
Oracle还有一个名为"动态采样"的功能,用于对表进行采样,以确定执行时的相关统计信息.它经常用于数据仓库,其中采样的开销远远超过长期运行查询的潜在性能提升.
如果分析所涉及的表,这种类型的问题通常会消失(因此Oracle更好地了解数据的分布)
ANALYZE TABLE tasks COMPUTE STATISTICS;
Run Code Online (Sandbox Code Playgroud)