sql,查询优化和内连接?

时间:2012-02-26 11:33:40

标签: sql join query-optimization

我正在尝试优化我的查询,它有一个内连接和合并。

连接表很简单,只有一个整数字段的表,我添加了一个唯一的密钥。

对于我的where子句,我为这三个字段创建了一个键。

但是当我看到这个计划时,它仍然说它正在使用表扫描。

我哪里错了?

这是我的查询

select date(a.startdate, '+'||(b.n*a.interval)||' '||a.intervaltype) as due

from billsndeposits a 

inner join util_nums b on date(a.startdate, '+'||(b.n*a.interval)||' 
     '||a.intervaltype) <= coalesce(a.enddate, date('2013-02-26')) 

where not (intervaltype = 'once' or interval = 0) and factid = 1 

order by due, pid;

2 个答案:

答案 0 :(得分:3)

很可能你的JOIN表达式不能使用任何索引,它是通过自然扫描计算的,并为每一行计算date(a.startdate, '+'||(b.n*a.interval)||' '||a.intervaltype)

BTW:这本身就是一个非常奇怪的连接条件。我建议您找到一种更好的方式将billsndeposits加入util_nums(如果确实需要)。

答案 1 :(得分:2)

我想我明白你想要实现的目标。但是这种联接是缓慢表现的一个因素。即使您删除日期计算和合并(即将一个日期与另一个日期进行比较),即使使用索引,它仍然会很慢(与整数联接相比)。而且因为您正在动态创建新日期,所以无法将它们编入索引。

我建议创建一个临时表,其中包含2列(1)pid(或billsndeposits中使用的任何ID)和(2)recurrence_dt

使用此查询填充新表:

INSERT INTO TEMP
SELECT PID, date(a.startdate, '+'||(b.n*a.interval)||' '||a.intervaltype)
FROM billsndeposits a, util_numbs b;

然后在recurrence_dt列和runstats上创建索引。现在你的select语句看起来像这样:

SELECT recurrence_dt
FROM temp t, billsndeposits a
WHERE t.pid = a.pid
  AND recurrence_dt <= coalesce(a.enddate, date('2013-02-26'))

您可以在此新表上添加exp_ts,然后使临时数据过期。

我知道这会为原始查询添加更多工作,但这可以保证性能的提升,并且应该自然地适合经常运行的脚本。

此致

修改

我要做的另一件事是make enddate default value = date('2013-02-26'),除非它会影响其他代码和/或没有商业意义。这样您就不必使用合并。