Oracle子查询在大型数据集上的SELECT MAX()非常慢

时间:2017-11-21 12:23:18

标签: sql oracle join subquery

以下SQL:

SELECT *
FROM   Transaction_Auth_Series t
WHERE  t.Auth_ID = 
(
  SELECT MAX(p.Session_ID)
  FROM   Clone_Db_Derective p
  WHERE  p.Date = trunc(sysdate)
  AND    p.Regularity = 'THEME'
);
当引用的表包含大约3亿行时,

非常慢。但是,当用两个游标编写SQL时,只需几秒钟,即

  CURSOR GetMaxValue IS
    SELECT MAX(p.Session_ID)
      FROM   Clone_Db_Derective p
      WHERE  p.Date = trunc(sysdate)
      AND    p.Regularity = 'THEME'

  CURSOR GetAllItems(temp VARCHAR2) IS
    SELECT *
    FROM   Transaction_Auth_Series t
    WHERE  t.Auth_ID = temp;

........
  FOR item in GETMAX LOOP
    FOR itemx in GETITEMS(item.aaa) LOOP.......

由于表格不相关,因此联接不起作用。我们怎样才能优化上面的主要SQL?

2 个答案:

答案 0 :(得分:0)

对于此查询:

SELECT t.*
FROM Transaction_Auth_Series t
WHERE t.Auth_ID = (SELECT MAX(p.Session_ID)
                   FROM Clone_Db_Derective p
                   WHERE p.Date = trunc(sysdate) AND p.Regularity = 'THEME'
                  );

我建议Clone_Db_Derective(Regularity, Date, Session_ID)Transaction_Auth_Series(Auth_Id)上的索引。

此查询的优化(假设表不是视图)似乎非常简单。我很惊讶光标版本的速度要快得多。

答案 1 :(得分:0)

WITH max_session
     AS (SELECT MAX (p.Session_ID) id
           FROM Clone_Db_Derective p
          WHERE p.Date = TRUNC (SYSDATE) AND p.Regularity = 'THEME')
SELECT *
  FROM Transaction_Auth_Series t
 WHERE t.Auth_ID = (SELECT id FROM max_session)

如果在主查询的主体中需要多次使用WITH查询的结果,例如需要将一个平均值与两次或三次进行比较,则WITH子句最有价值。重点是尽量减少对多次连接到一个查询的表的访问次数。