[英]Oracle:query optimization
我有两个表tab1
和tab2
。 tab1
有108000行,而tab2
有1200000行。
这是样本数据
tab1
+-----------------------------------------------------+
| Low | high | Region_id |
+-----------------------------------------------------+
|5544220000000000 | 5544225599999999 | 1 |
|5544225500000000 | 5544229999999999 | 2 |
|5511111100000000 | 5511111199999999 | 3 |
+-----------------------------------------------------+
tab2
+------------------+
| pan |
+-------------------
|5544221111111111 |
|5544225524511244 |
|5511111111254577 |
+------------------+
所以我运行这样的查询
select t2.pan, t1.region_id from tab2 t2
join tab1 t1 on t2.pan between t1.low and t1.high;
我想做的是查找tab2.pan
在哪个范围内并检索到它的region_id
:范围是唯一的,这意味着高低对是不同的。
我尝试添加并行运行的索引,但是查询运行非常慢(大约3小时)。 任何人都可以提出一些建议来加强查询,可以添加某种索引,或更改数据结构或其他任何内容。
我正在针对Oracle 11gR2运行查询。
UPDATE
从评论中我测试了几件事
添加索引(如(高,低)并添加索引(pan)和(高,低,区域)),两种方式都进行索引全扫描,我也尝试了on(低,high)索引和pan索引,这种方式就是索引在tab1上进行范围扫描,在tab2上进行索引全扫描,但是无论如何它似乎都非常慢。
如果没有重叠,并且tab1
中的每个值都恰好匹配tab2
一行,那么我认为最好的方法是使用正确索引的相关子查询:
select t.*, t2.region_id
from (select t1.*,
(select max(t2.low)
from tab2 t2
where t2.low <= t.pan
) as t2low
from tab1 t1
) t join
tab2 t2
on t.t2low = t2.low;
您想要的索引是tab2(low, region)
。 该索引应非常有效地用于子查询以获取最接近的low
。 然后,连接也应该非常快。
这对您的表现有帮助吗?
编辑:
我应该注意,在上面的查询中,您可以测试外部联接中的high
值。 如果low
是唯一的,这应该没问题,因为low
的连接将非常快。 所以:
select t.*,
(case when t.pan <= t2.high then t2.region_id end) as region_id
from (select t1.*,
(select max(t2.low)
from tab2 t2
where t2.low <= t.pan
) as t2low
from tab1 t1
) t join
tab2 t2
on t.t2low = t2.low;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.