提高绩效

时间:2012-09-04 11:24:07

标签: sql oracle oracle8i

我并不像SQL中的快捷方式那样,所以我希望利用这里的智能来帮助加快我正在使用的查询速度。我目前正在使用Oracle 8i。

我有一个问题:

SELECT 
    NAME_CODE, ACTIVITY_CODE, GPS_CODE 
FROM
    (SELECT 
         a.NAME_CODE, b.ACTIVITY_CODE, a.GPS_CODE, 
         ROW_NUMBER() OVER (PARTITION BY a.GPS_DATE ORDER BY b.ACTIVITY_DATE DESC) AS RN
     FROM GPS_TABLE a, ACTIVITY_TABLE b
     WHERE a.NAME_CODE = b.NAME_CODE
       AND a.GPS_DATE >= b.ACTIVITY_DATE 
       AND TRUNC(a.GPS_DATE) > TRUNC(SYSDATE) - 2)
WHERE 
    RN = 1

这需要大约7分钟给出或需要10秒钟才能运行。

现在GPS_TABLE目前是6.586.429行并且随着新的GPS坐标被放入系统而继续增长,每天它增长了6列中的大约8.000行。

ACTIVITY_TABLE当前为1.989.093行,并且随着新活动投放到系统中而持续增长,每天它在31列中增长约2.000行。

所有这些都不是小表,我知道运行这个或类似的查询总会有时间。正如你所看到的,我已经将它限制在最后2天的数据中,但是任何加速它的东西都会受到赞赏。

2 个答案:

答案 0 :(得分:3)

您最强的过滤器似乎是GPS_TABLE过去2天的过滤器。它应该将GPS_TABLE过滤到大约15k行。因此,改进的最佳候选者之一是列GPS_DATE上的索引。

您会发现过滤器TRUNC(a.GPS_DATE) > TRUNC(SYSDATE) - 2等同于a.GPS_DATE > TRUNC(SYSDATE) - 2,因此如果更改查询,您的列上的简单索引就会生效。如果您无法更改它,则可以在TRUNC(GPS_DATE)上添加基于函数的索引。

准备好此索引后,我们需要访问ACTIVITY_TABLE中的行。您加入的问题是我们将获得所有旧活动,因此我们将获得该表的很大一部分。这意味着索引扫描无法实现连接效果。

我建议您在ACTIVITY_TABLE(name_code, activity_date DESC)和PL / SQL函数上定义一个索引,该函数将使用此索引专门检索最少量工作中的最后一个活动:

CREATE OR REPLACE FUNCTION get_last_activity (p_name_code VARCHAR2, 
                                              p_gps_date DATE) 
RETURN ACTIVITY_TABLE.activity_code%type IS
   l_result ACTIVITY_TABLE.activity_code%type;
BEGIN
   SELECT activity_code
     INTO l_result
     FROM (SELECT activity_code
             FROM activity_table
            WHERE name_code = p_name_code
              AND activity_date <= p_gps_date
            ORDER BY activity_date DESC)
     WHERE ROWNUM = 1;
   RETURN l_result;
END;

修改您的查询以使用此功能:

SELECT a.NAME_CODE,
       a.GPS_CODE,
       get_last_activity(a.name_code, a.gps_date)
  FROM GPS_TABLE a
 WHERE trunc(a.GPS_DATE) > trunc(sysdate) - 2

答案 1 :(得分:1)

优化SQL查询通常通过以下方式完成:

  1. 添加一些索引
  2. 尝试以不同的方式获取相同的信息
  3. 首先,添加ACTIVITY_DATE的索引,以及条件中使用的其他一些字段。