您好我创建了一个带有范围列表分区的FACT TABLE。
范围分区是DATE_REG(01/2013,...,01 / 2014,02 / 2014,......)的月份。 列表子分区用于字符串TYPE_R(' A',' B',' C')。
主要索引是
在FACT_TABLE(DATE_REG)上创建INDX 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子句时,执行时间是2.35秒,但是当我考虑按顺序时间改为125秒时。
我知道这个问题是因为当order by处于活动状态时,它通过所有行,而DATE_REG的Range在多个分区中。
我的问题是:我如何优化此查询?
提前致谢。
更新
我的查询是(案例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万行。
答案 0 :(得分:0)
您的where
条款对我没有意义:
WHERE DATE_REG >= '01/01/2013' AND -- DD/MM/YYYY
DATE_REG >= '01/11/2013' AND
TYPE_R = 'B'
ORDER BY DATE_REG ASC
这相当于:
WHERE DATE_REG >= '01/11/2013' AND
TYPE_R = 'B'
ORDER BY DATE_REG ASC
我对使用“DD / MM / YYYY”格式感到不舒服,所以我认为这可以更好地表达为:
WHERE DATE_REG >= to_date('01/11/2013', 'DD/MM/YYYY') AND
TYPE_R = 'B'
ORDER BY DATE_REG ASC
至于order by
查询的性能,可能是由于数据量大。排序确实需要时间,在这种情况下,如何安排Oracle使用索引还不清楚。