我有两张桌子:
我需要优化以下select语句
select r.id_range, sum(t.delta) sum_deltas
from trips t,
ranges r
where t.id_object = r.id_object
and t.trip_date between r.date_since and r.date_until
group by r.id_range
根据条件,在'范围内始终只有一个匹配的旅行行
有没有人知道如何加快速度,甚至可能?
答案 0 :(得分:1)
您可能希望查看数据分段(即按特定日期对数据进行分区,导致查询仅访问相应的分区)和索引,这些可能会加快查询过程。
此外,您可以考虑使用数据仓库......您说Trips永远不会被更新或删除,因此它是非规范化为更适合报告生成和即席查询的数据结构的理想候选者。
答案 1 :(得分:1)
总是可以加快速度;它可能不值得花时间/精力/金钱/磁盘空间/额外开销等。
首先请使用显式连接语法。几十年来它一直是SQL标准,它有助于避免许多潜在的错误。您的查询将变为:
select r.id_range, sum(t.delta) sum_deltas
from trips t
join ranges r
on t.id_object = r.id_object
and t.trip_date between r.date_since and r.date_until
group by r.id_range
此查询意味着您需要两个索引 - 如果可能,则为唯一索引。在ranges
上,您应该在id_object, date_since, date_until
上有一个索引。 trips
上的索引为id_object, trip_date
。如果trips
较小,我可以考虑将delta
添加到该索引的末尾,这样您就不会输入表,只会进行索引扫描。就目前而言,您将不得不通过索引rowid进行表访问。
写完所有问题可能会略有不同。您将使用此查询对这两个表进行全面扫描。您的问题可能是索引。如果优化器正在使用索引,那么您可能正在为id_object
或trips
中的每个ranges
执行索引唯一/范围扫描,然后,因为使用的列不在您将通过索引rowid对表进行访问的索引。这可能非常昂贵。
尝试添加hint以强制对两个表进行全面扫描:
select /*+ full(t) full(r) */ r.id_range, sum(t.delta) sum_deltas
from trips t
join ranges r
on t.id_object = r.id_object
and t.trip_date between r.date_since and r.date_until
group by r.id_range