Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 执行查询需要较长时间_Oracle_Subquery - Fatal编程技术网

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;