Oracle日期和时间提示

问题描述 投票:0回答:2

我有一个表,其中包含带有日期和时间的列,该表的用户希望能够选择最新的行。现在,该表有很多行,而我说的不是几十万行。

最简单的方法是按降序排序,但是由于行数如此之多,所以这不是很好的性能选择。该列是索引,但是我想知道是否可以将oracle提示放入select中以更快地运行查询。

任何人都具有使用如此大表根据最新日期和时间选择行的经验吗?

oracle oracle10g
2个回答
0
投票

如@Wernfried所说,10g有点过时了。所以呢?我也使用它(对于某些应用程序)。由于您无法更改它,因此,我们尝试找到一种使其变得更快的方法。看看这个选项,看看是否有帮助。

模仿“您的表”的样本表,作为Scott的EMP表的副本。索引date列(如果有的话):

SQL> create table your_table as select * From emp;

Table created.

SQL> create index i1 on your_table (hiredate);

Index created.

SQL> alter session set nls_date_Format = 'dd.mm.yyyy';

Session altered.

SQL> select empno, ename, hiredate from your_table order by hiredate desc;

     EMPNO ENAME      HIREDATE
---------- ---------- ----------
      7876 ADAMS      12.01.1983
      7788 SCOTT      09.12.1982
      7934 MILLER     23.01.1982
      7902 FORD       03.12.1981
      7900 JAMES      03.12.1981
      7839 KING       17.11.1981
      7654 MARTIN     28.09.1981
      7844 TURNER     08.09.1981
      7782 CLARK      09.06.1981
      7698 BLAKE      01.05.1981
      7566 JONES      02.04.1981
      7521 WARD       22.02.1981
      7499 ALLEN      20.02.1981
      7369 SMITH      17.12.1980

14 rows selected.

SQL>

现在,idea本身:创建一个仅包含一行的新表-hiredate,当前在表中为MAX:

SQL> create table maxdat (maxdat date);

Table created.

SQL> -- Initial insert
SQL> insert into maxdat (maxdat) select max(hiredate) from your_table;

1 row created.

SQL> select * From maxdat;

MAXDAT
----------
12.01.1983

SQL>

为了维护maxdat表,创建一个数据库触发器-如果表中新添加(或更新)的MAXDAT大于hiredate,它将替换当前的MAXDAT列值:

SQL> create or replace trigger trg_aiu_yourt
  2    after insert or update on your_table
  3    for each row
  4  declare
  5    l_maxdat maxdat.maxdat%type;
  6  begin
  7    merge into maxdat m
  8      using (select :new.hiredate as hiredate from dual) x
  9      on (1 = 1)
 10    when matched then update set
 11      m.maxdat = x.hiredate
 12    where x.hiredate > m.maxdat;
 13  end;
 14  /

Trigger created.

SQL> select * from maxdat;

MAXDAT
----------
12.01.1983

SQL>

让我们强制MAXDAT更改(现在,员工FORD将具有最高的hiredate列值:]

SQL> update your_table set hiredate = date '1984-01-01' where ename = 'FORD';

1 row updated.

SQL> select * From maxdat;

MAXDAT
----------
01.01.1984

SQL>

最后,您的查询现在不必扫描整个巨大的表(实际上是索引),而是一个单行表:maxdat

SQL> select y.empno, y.ename, y.job, y.sal, y.hiredate
  2  from your_table y cross join maxdat m
  3  where y.hiredate = m.maxdat;

     EMPNO ENAME      JOB              SAL HIREDATE
---------- ---------- --------- ---------- ----------
      7902 FORD       ANALYST         3000 01.01.1984

SQL>

由于hiredate列已建立索引,并且您知道maxdat值,所以此可能相当快。

可能的缺点:如果your_table中有大量并发插入/更新,触发器可能会减慢速度,但是-没有免费的午餐。


0
投票

抱歉-没有大型表中日期/时间列的特定经验。

您可以尝试:

  • FIRST_ROWS提示(Oracle 10g docs),
  • 创建索引,其中包括所有相关列以将行程保存到实际行,或者
  • 按日期对表进行分区。

请评论,如果并且因为这需要调整/进一步的细节。

© www.soinside.com 2019 - 2024. All rights reserved.