【发布时间】:2014-07-25 18:33:36
【问题描述】:
您好,我用范围列表分区创建了一个 FACT TABLE。
范围分区为月份 DATE_REG ( 01/2013, ... ,01/2014, 02/2014, ....)。 列表子分区用于字符串 TYPE_R('A'、'B'、'C')。
主索引是
在 FACT_TABLE (DATE_REG) 上创建索引 INX_DATE_REG
我的查询是
Select
....
FROM FACT_TABLE
INNER JOIN A ...
INNER JOIN B ...
INNER JOIN C ...
INNER JOIN D ...
INNER JOIN E ...
WHERE DATE_REG >= '01/01/2013' -- DD/MM/YYYY
AND DATE_REG < '01/01/2014'
AND TYPE_R = 'B'
ORDER BY DATE_REG ASC
当我省略 ORDER BY Clause 时,执行时间是 2.35 秒,但是当我考虑 Order By 时,时间更改为 125 秒。
我知道这个问题是因为当order by处于活动状态时,它通过所有行,并且DATE_REG的范围在多个分区中。
我的问题是:如何优化这个查询?
提前致谢。
更新
当我的查询是(案例 1)时:
Select
ft.x,
ft.y,
...
ft.xxxxx
FROM FACT_TABLE ft
INNER JOIN A ...
INNER JOIN B ...
INNER JOIN C ...
INNER JOIN D ...
INNER JOIN E ...
WHERE DATE_REG >= '01/01/2013' -- DD/MM/YYYY
AND DATE_REG < '01/01/2014'
AND TYPE_R = 'B'
ORDER BY DATE_REG ASC
时间是 15 秒。
当我的查询是(案例 2)时:
Select
ft.x,
ft.y,
...
ft.xxxxx,
E.abc
FROM FACT_TABLE ft
INNER JOIN A ...
INNER JOIN B ...
INNER JOIN C ...
INNER JOIN D ...
INNER JOIN E ...
WHERE DATE_REG >= '01/01/2013' -- DD/MM/YYYY
AND DATE_REG < '01/01/2014'
AND TYPE_R = 'B'
ORDER BY DATE_REG ASC
时间是 150 秒。 abd 是一个没有索引的列。
当我的查询是(案例 3):
Select
*
FROM FACT_TABLE ft
INNER JOIN A ...
INNER JOIN B ...
INNER JOIN C ...
INNER JOIN D ...
INNER JOIN E ...
WHERE DATE_REG >= '01/01/2013' -- DD/MM/YYYY
AND DATE_REG < '01/01/2014'
AND TYPE_R = 'B'
ORDER BY DATE_REG ASC
时间是 17 秒。
当查询从另一个表调用额外的列时排序变慢,但是当我调用所有列(案例 3)时,时间小于案例 2。
解释计划_案例1
解释计划 _ 案例 2
此时每个分区包含 250 万行。
【问题讨论】:
-
“seg”是“seconds”的缩写吗(通常缩写为“sec”)?您是否正在测量获取第一行所需的时间?或者获取最后一行所需的时间?您的查询返回多少行?
-
对不起,我更正了。我的测试是针对第一行的。大约有 8000/16000000 行。我刚刚添加了新信息。谢谢
-
测量获取第一行所需的时间会使比较不合理。为了在您指定
order by时返回第一行,需要获取所有行并对其进行排序。为了返回没有order by的第一行,Oracle 不需要首先具体化结果集。但是,您发布的三个查询中没有一个缺少order by。查询 1 和 2 似乎相同。查询 3 似乎仅在select列表中的列列表中有所不同。这真的是唯一的区别吗? -
是的,唯一的区别是在另一个表中添加不是外键的列时,第二次查询会变慢。你的问题是,是否有可能只添加一列随着时间的推移而发生很大变化?当我查阅所有列时,时间比特定列时短。
标签: oracle oracle11g query-optimization