我有两条潜在的道路可以解决以下问题,尝试它并看到方法无法为此解决方案带来回报,因为服务器上的负载不断变化。我有两种方法如下:
select *
from
(
select foo.a,bar.b,baz.c
from foo,bar,baz
-- updated for clarity sake
where foo.a=b.bar
and b.bar=baz.c
)
group by a,b,c
副
create table results as
select foo.a,bar.b,baz.c
from foo,bar,baz
where foo.a=b.bar
and b.bar=baz.c ;
create index results_spanning on results(a,b,c);
select * from results group by a,b,c;
所以如果不清楚的话。顶部查询完全针对多表选择执行组,从而阻止我使用索引。第二个查询允许我创建一个新表来存储查询结果,继续创建生成索引,然后按查询完成组以利用索引。
这两种方法的复杂性差异是什么,即它们如何扩展,哪种在大量数据的情况下更可取。此外,主要问题是整体选择的性能,所以这就是我试图解决的问题。
评论
你真的在三张桌子上做CROSS JOIN吗?那三个 列自己索引了吗?你多久想跑一次 提供最终结果的查询?
1)不。
2)是的,为了讨论省略了哪个条款,因为这显然是一个非常简单的例子
3)没关系。
第二次更新
这是一个临时表,因为它只在短时间内有效,所以是的,这个表只会被查询一次。
答案 0 :(得分:0)
所以问题是,哪个更快?
运行一次查询并对结果集进行排序?
运行一次查询以构建表,然后构建索引,然后再次运行查询并对结果集进行排序?
嗯。棘手的。
临时表的用例在Oracle中非常罕见。它们通常仅在我们需要冻结结果集时应用,然后我们将重复查询。这显然不是这种情况。
因此,请选择第一个选项,并在必要时调整查询。
答案是,调整问题的情况经常如此,这取决于。
为什么你首先要做GROUP BY。发布它时的查询不会进行任何聚合,因此执行GROUP BY的唯一原因是消除重复行,即DISTINCT操作。如果实际情况是这样,那么你做某种形式的笛卡尔连接,一个调整查询就是修复WHERE子句,使它只返回离散记录。
答案 1 :(得分:0)
如果您的查询经常执行且速度慢得令人无法接受,您可以考虑创建实体化视图以预先计算结果。这为您提供了可索引“表”的好处,而且没有每次创建表的开销。
如果表格很大,您需要刷新实体化视图(fast
或on commit
。在如何创建提交,快速刷新视图方面存在一些限制,它们会稍微增加您的提交时间,但它们将始终提供与运行基本查询相同的结果。随着基础数据的变化,MV会变得陈旧,直到刷新为止。您需要确定这是否可以接受。