Oracle SQL查询优化-根据varchar字段获取计数

时间:2019-02-19 17:48:46

标签: sql oracle

优化查询

我有一个查询从一个表中获取数据,并从另外两个表中获取两个计数 在varchar字段TYPE上。我需要从TABLE2那里获得计数,其中TYPE = TABLE1.TYPE和 从TABLE3计数,其中TYPE = TABLE1.TYPE

这时我无法在这些字段上创建任何索引,因此我决定使用带来原始查询执行时间的函数 降至5秒,这仍然太多了。有关如何进一步优化查询的任何建议?

 SELECT     a.ID, 
    a.FIELD1, 
    a.FIELD2, 
    a.TYPE, 
    GET_COUNT_1(a.TYPE) as COUNT1,
    GET_COUNT_2(a.TYPE) as COUNT2,
FROM TABLE1 a

我原来的查询是:

SELECT  a.ID, 
    a.FIELD1, 
    a.FIELD2, 
    a.TYPE, 
    (SELECT COUNT(*) FROM TABLE2 b WHERE b.TYPE=a.TYPE) as COUNT1,
    (SELECT COUNT(*) FROM TABLE3 c WHERE c.TYPE=a.TYPE) as COUNT2
FROM TABLE1 a

2 个答案:

答案 0 :(得分:3)

如果您在table2(TYPE)上没有索引,则使用子查询是致命的,因为您将反复(对于TABLE1的每一行)执行 FULL TABLE SCAN

显然,可以节省您费用的Oracle子查询兑现没有成功。

除了您自己实现一些功能结果缓存外,函数方法不会有什么更好的

但是有一个简单的解决方案可以预先计算子查询中的计数,并将结果加入TABLE1

请注意,您仅对每种类型count进行一次计算,而不对TABLE1的每一行进行计算

with cnt as 
(select type, count(*) cnt
from table2 group by type),
cnt2 as 
    (select type, count(*) cnt
    from table3 group by type)
select a.ID, 
    a.FIELD1, 
    a.FIELD2, 
    a.TYPE,
    b.cnt cnt1
    c.cnt cnt2
from  TABLE1 a 
left outer join cnt b
on a.type = b.type
left outer join cnt2 c
on a.type = c.type

对于每个表,聚合和外部联接,您将以一个FTS结尾,这是您要做的最少工作。

答案 1 :(得分:-1)

对于您的查询,您需要在table2(type)上建立索引。

除了表别名外,这两个子查询完全相同。如果确实有两个不同的表,或者使用的是不同的列,则需要该表达式的适当索引。