Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.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
Sql 在oracle数据库中查找最新日期_Sql_Oracle_Row Number_Rownum - Fatal编程技术网

Sql 在oracle数据库中查找最新日期

Sql 在oracle数据库中查找最新日期,sql,oracle,row-number,rownum,Sql,Oracle,Row Number,Rownum,我在oracle数据库版本10中的查询中遇到了一个大问题。我想要的是找到dateofstat的最后一个日期 我尝试了很多解决方案,但都很有效,但花费了太多的时间。 -使用rownum -使用行号 -使用秩 以下是我的尝试: 1.罗努姆 解释计划: 行号 解释计划: 排名:这个解决方案我确实尝试过,但它给出了重复的排名数字,因为它,我认为我不应该用这个解决方案来找到排名靠前的那个 我不知道现在该怎么办,真的需要帮助。为了进行测试,我在emacs上使用sqlplus,在没有rownum的情况下,

我在oracle数据库版本10中的查询中遇到了一个大问题。我想要的是找到dateofstat的最后一个日期 我尝试了很多解决方案,但都很有效,但花费了太多的时间。 -使用rownum -使用行号 -使用秩

以下是我的尝试: 1.罗努姆

解释计划:

行号

解释计划:

排名:这个解决方案我确实尝试过,但它给出了重复的排名数字,因为它,我认为我不应该用这个解决方案来找到排名靠前的那个

我不知道现在该怎么办,真的需要帮助。为了进行测试,我在emacs上使用sqlplus,在没有rownum的情况下,我用不到3秒钟的时间获取此查询的第一行

select  stat.dateofstat from dhg.statistics stat
join (
  select distinct assetid from dhg.relatedasset
     where (`CONDITION1`)
  MINUS
  select distinct assetid from dhg.relatedasset
 where (`CONDITION2`)
) grs 
on stat.assetid = grs.assetid
order by stat.dateofstat desc
我想知道,我可以有任何解决办法,通过这种调整

从@ANTON更新解决方案状态

我必须说,我曾经工作过,非常奇怪的行为。在第一次执行中,我只花了3秒钟来执行,但在第二次执行中,我花的时间多得多,我没有计算在内。以下是详细的计划:

此外,我还尝试了使用exist和notexists的第二个解决方案,但效果不好

select  max(stat.dateofstat)
from dhg.statistics stat
where exists(select *
           from dhg.relatedasset rasset
           where stat.assetid = rasset.assetid
           and rasset.assetid in (191759.0, 3.0, 5.0, 98.0, 99.0)
           or rasset.linkid in (3232.0, 1049.0, 1057.0, 1067.0, 102.0, 1032.0, 104.0, 105.0, 1051.0)
            )
and not exists (select *
           from dhg.relatedasset rasset2
           where stat.assetid = rasset2.assetid
           and rasset2.assetid in (192106.0, 1014.0, 10302.0)
           or rasset2.linkid in (210.0, 737.0, 126.0, 1053.0, 1054.0, 119.0, 3133.0)
            )
这个疑问,这个计划给了我一个痛苦的结果。 为什么这么复杂? 如果您只需要最后日期,可以使用max函数:

select  max(stat.dateofstat)
from dhg.statistics stat
join (
  select distinct assetid from dhg.relatedasset
     where (`CONDITION1`)
  MINUS
  select distinct assetid from dhg.relatedasset
 where (`CONDITION2`)
) grs 
on stat.assetid = grs.assetid
如果dhg.statistics表不是太大,并且您可能会假设只需要探测几个dateofstat最高的记录,以找到一个符合您的相关资产要求的记录,那么您可以像这样重写查询:

select  max(stat.dateofstat)
from dhg.statistics stat
where exists(select *
               from dhg.relatedasset asset1
              where (`CONDITION1`)
                and stat.assetid = asset1.assetid)
 and not exists (select *
               from dhg.relatedasset asset2
              where (`CONDITION2`)
                and stat.assetid = asset2.assetid)
但若您需要在relatedasset表中执行太多的探测来查找所需的统计信息,那个么性能可能会更差。 根据新计划进行更新 Sstan是正确的,因为统计表大71M,负结果小5,所以只需要对相关资产表进行适当的索引 我建议按relatedasset.assetid和relatedasset.linkid、relatedasset.assetid进行索引,以避免表扫描。 顺便说一下,您在第二个查询中遗漏了括号
由于和的优先级比括号中的条件1和条件2更高,所以需要获得正确的WHERE条件,所以您得到的计划比可能的要糟糕得多。但无论如何,使用这种数据分布,即使是正确的版本,也会比使用适当索引的varian执行得慢。

看起来您只是缺少索引。确保您在以下各项上具有索引:

relatedasset.assetid relatedasset.linkid
一旦这样做,所有尝试的查询都会执行得更好。

由于relatedasset中和或上的各种OR条件,DBMS决定执行完整表扫描。这似乎是合理的。那么我们可以优化什么呢?我们可以确保只进行一次完整的表扫描。查询表,按assetid分组,并使用Have检查第一个条件是否适用于任何记录,第二个条件是否适用于任何记录

如果可能的话,还可以使用并行提示使Oracle并行执行完整表扫描

select  max(dateofstat)
from dhg.statistics
where assetid in
(
  select /*+ parallel(relatedasset,4) */ assetid
  from dhg.relatedasset 
  group by assetid
  having 
    max( case when assetid in (191759.0, 3.0, 5.0, 98.0, 99.0) 
                or linkid in (3232.0, 1049.0, 1057.0, 1067.0, 102.0, 1032.0, 104.0, 105.0, 1051.0) 
         then 1 else 0 end ) = 1
  and
    max( case when assetid in (192106.0, 1014.0, 10302.0)
                or linkid in (210.0, 737.0, 126.0, 1053.0, 1054.0, 119.0, 3133.0) 
         then 1 else 0 end ) = 0
);

如果您真的在寻找一个性能问题,那么看起来您的做法是错误的,并且没有向我们提供查询中最重要的部分:条件1和条件2。这就是导致全表扫描的原因。您是否检查过这些条件中使用的列是否正确索引?我确实提供了条件1,2的详细信息,请参见我确实尝试过,但效果不好,我在问题更新中发布了解决方案状态。请看一看,我必须说,你的解决方案太疯狂了。它像魅力一样,用更少的时间工作。现在我要分析你的解决方案,为什么它工作得这么快。谢谢。我有一个问题,in子句只能处理1000个元素,但是,您在这里使用子查询,所以从长远来看,它会造成麻烦吗。事实上,子查询后面的子查询返回6000多个结果是的,限制仅限于文本。这是我非常讨厌的限制。每次我有上千个文本时,我都必须将它们拆分成单独的IN子句,然后与临时表结合使用。甲骨文也可以允许1000多个文本,并在隐蔽的情况下做同样的事情。
select  max(stat.dateofstat)
from dhg.statistics stat
join (
  select distinct assetid from dhg.relatedasset
     where (`CONDITION1`)
  MINUS
  select distinct assetid from dhg.relatedasset
 where (`CONDITION2`)
) grs 
on stat.assetid = grs.assetid
select  max(stat.dateofstat)
from dhg.statistics stat
where exists(select *
               from dhg.relatedasset asset1
              where (`CONDITION1`)
                and stat.assetid = asset1.assetid)
 and not exists (select *
               from dhg.relatedasset asset2
              where (`CONDITION2`)
                and stat.assetid = asset2.assetid)
select  max(dateofstat)
from dhg.statistics
where assetid in
(
  select /*+ parallel(relatedasset,4) */ assetid
  from dhg.relatedasset 
  group by assetid
  having 
    max( case when assetid in (191759.0, 3.0, 5.0, 98.0, 99.0) 
                or linkid in (3232.0, 1049.0, 1057.0, 1067.0, 102.0, 1032.0, 104.0, 105.0, 1051.0) 
         then 1 else 0 end ) = 1
  and
    max( case when assetid in (192106.0, 1014.0, 10302.0)
                or linkid in (210.0, 737.0, 126.0, 1053.0, 1054.0, 119.0, 3133.0) 
         then 1 else 0 end ) = 0
);