Oracle 执行查询需要较长时间
是否有任何方法可以减少从下面的查询中获取结果所需的时间? 请帮忙。提前谢谢Oracle 执行查询需要较长时间,oracle,subquery,Oracle,Subquery,是否有任何方法可以减少从下面的查询中获取结果所需的时间? 请帮忙。提前谢谢 select status, count(distinct id) from emp where id >= ( select min(id) from emp where id >= (select max(id-200000) from emp) and trunc(join_date) >= '01-Mar-2018') group
select status, count(distinct id)
from emp
where id >=
( select min(id)
from emp
where id >= (select max(id-200000) from emp)
and trunc(join_date) >= '01-Mar-2018')
group by status;
使用分析函数-这将只执行一次表扫描(而您的查询有三次表/索引扫描):
此外,您可以使用日期文字(而不是依赖于使用
NLS\u date\u FORMAT
session参数将字符串隐式转换为日期),并且不需要使用TRUNC()
函数(因为这可能会阻止Oracle在join\u date
列上使用索引,而需要基于函数的索引)。使用分析函数-这将只执行一次表扫描(而您的查询有三次表/索引扫描):
此外,您可以使用日期文字(而不是依赖于使用
NLS\u date\u FORMAT
session参数将字符串隐式转换为日期),并且不需要使用TRUNC()
函数(因为这可能会阻止Oracle在join\u date
列上使用索引,而需要基于函数的索引)。重要的是要知道id是否是主键(通常具有该名称的列都是主键)。如果不是,您肯定需要id上的索引才能执行此操作(我还想知道该列的用途是什么)。如果id是主键,则不需要使用distinct
,因为值无论如何都是唯一的
select min(id)
sub-select是多余的,因为您已经找到了max(id-200000),所以您不需要知道大于该值的第一个min(id)。您只需使用>=本身(添加日期条件)。顺便说一句,我会改为编写max(id)-200000
;在某些数据库上,它可能工作得更好
日期比较可能有问题。如果您还没有索引,您应该尝试在join_date
上建立索引,但是trunc
可能会阻止使用该索引,因此最好删除该索引,并使比较的另一端使用to_TIMESTAMP
或to_date
来生成相应的文本l根据情况,将时间设置为午夜
但是,由于时区等原因,在比较时间戳时可能会出现问题。我需要了解有关您的设置的更多信息,以了解这是否可能是一个问题。重要的是要知道id是否是主键(通常具有该名称的列都是主键)。如果不是,您肯定需要id上的索引才能执行此操作(我还想知道该列的用途是什么)。如果id是主键,则不需要使用
distinct
,因为值无论如何都是唯一的
select min(id)
sub-select是多余的,因为您已经找到了max(id-200000),所以您不需要知道大于该值的第一个min(id)。您只需使用>=本身(添加日期条件)。顺便说一句,我会改为编写max(id)-200000
;在某些数据库上,它可能工作得更好
日期比较可能有问题。如果您还没有索引,您应该尝试在join_date
上建立索引,但是trunc
可能会阻止使用该索引,因此最好删除该索引,并使比较的另一端使用to_TIMESTAMP
或to_date
来生成相应的文本l根据情况,将时间设置为午夜
但是,由于时区等原因,在比较时间戳时可能会出现问题。我需要了解有关您的设置的更多信息,以了解这是否可能是一个问题。您好,欢迎使用StackOverflow。请花些时间阅读帮助页,特别是名为和的部分。更重要的是,请阅读。您可能还想了解n关于.Schema,索引,解释计划-这些是有点必要的id是主键吗?如果不是,它还有索引吗?您好,欢迎来到StackOverflow。请花一些时间阅读帮助页面,特别是名为和的部分。更重要的是,请阅读。您可能还想了解.Schema,索引,解释计划-se有点必要id是主键吗?如果不是,它还有索引吗?如果
id
是按join\u date
的顺序生成的,那么min(id)
可能是多余的(OP需要确认这一点),但是如果id
和join\u date
没有顺序,那么min(id)
子查询不是多余的,因为您可以获得id
s,其join_date
早于仍然在min
和max-20000
之间的筛选器。此外,为什么要包含时间戳部分?OP没有使用它们,可以只使用日期文本。此外,不需要提及时间nes,因为OP没有使用它们,并且您引用的函数生成了一个时间戳
数据类型,而不是一个带有时区的时间戳(这就是函数所做的)。我认为这可以通过将日期where条件包含到选择max id的子查询中来解决(我误读了其中的括号).re timestamps:不清楚加入日期的类型。它可能是一个时间戳,在这种情况下,最好将它与时间戳进行比较(我应该说明清楚)。在问题中没有足够的内容来知道什么是最佳方法。如果id
是按join\u date
的顺序生成的,那么min(id)
可能是多余的(OP需要确认这一点),但如果id
和join\u date
不在顺序中,则min(id)
子查询不是多余的,因为您可以获得id
s,其join_date
早于仍然在min
和max-20000
之间的筛选器。此外,为什么要包含时间戳部分?OP没有使用它们,可以只使用日期文本。此外,不需要输入时间戳
SELECT status,
COUNT( DISTINCT id )
FROM (
SELECT status,
id,
MIN( CASE WHEN join_date >= DATE '2018-03-01' THEN id END ) OVER () AS min_id
FROM (
SELECT status,
id,
join_date,
MAX( id ) OVER () AS max_id
FROM emp
)
WHERE id >= max_id - 20000
)
WHERE id >= min_id
GROUP BY status;