寻找在oracle中减少大sql请求的时间

时间:2013-07-16 09:54:15

标签: sql oracle oracle11g

我有两张桌子: D与字段d1和字段d2 和田地的T. 这两个字段的类型为Varchar2(255)

select d2 
FROM 
D , 
(select s from T where (s = 'val_1') OR (s='val_2') OR .. OR (s='val_n')  ) S
WHERE d1 LIKE CONCAT(CONCAT('%,',S.s),'%')

我的问题是数字n很大(超过2500)

然后解决请求的时间大约是五分钟

是否有减少此时间的解决方案

2 个答案:

答案 0 :(得分:1)

让我们从D开始吧。这个WHERE子句......

WHERE d1 LIKE CONCAT(CONCAT('%,',S.s),'%')

......是致命的。这意味着查询需要探测 D1的每个值。没有常规索引可以帮助在每一端找到带有通配符的值。

现在让我们考虑T。这个WHERE子句......

 (s = 'val_1') OR (s='val_2') OR .. OR (s='val_n')

......显然有超过2500个元素。要调的纯毒。

尽管断言(在注释中)“表上没有索引”,但是已发布的创建表语句具有主键,因此可以使用索引。

但由于T似乎只有一列,因此列T.S上的索引没有任何区别:完全快速索引扫描与快速(或慢速)一样快全表扫描。假设S是一个非常慢的varchar2(255),因为该块的值不会很多。

由于已经说明的原因,D.D1上的索引无关紧要,因此我们再次将全表扫描作为唯一的访问路径。

那么我们希望的最佳执行计划是什么?类似的东西:

  1. T
  2. 的全表扫描
  3. 过滤2500+的S
  4. D
  5. 的全表扫描
  6. T.S和D.D1的哈希联接
  7. ...除了那些通配符将意味着嵌套循环操作而不是散列连接。

    最后让我们考虑一下这个陈述:

      

    “解决请求的时间大约是五分钟”

    调整中的单个帖子重要的是对经过的时间有合理的期望。在这种情况下,五分钟可能代表一种非常缓慢的反应或极快的反应。谁能说出来?我们当然不能。只有OP可以,因为只有他们可以访问数据,因此能够回答这些问题:

    • D1D2的平均长度是多少?
    • D中有多少行?
    • 阅读全部内容是否合理?
    • S的平均长度是多少?
    • T中有多少行?
    • 阅读全部内容是否合理?
    • TS匹配'%val_1%'到'%val_n%'的行数是多少?
    • D D1匹配'%val_1%'到'%val_n%'的行数{{1}}?
    • 什么是合理的时间来匹配它们?
    • 显示D2的所有相关值的合理时间是什么?

答案 1 :(得分:0)

每个主键创建索引时都有索引。但是,在匹配字符串开头使用带有“%”的LIKE会使索引无效。

但总的来说,拥有> 2500 OR条款暗示了一个更基本的问题。必须生成大量的OR子句,因为没有人会输入或编写这样的查询。在我看来,该部分查询已迁移到生成查询的代码。

所以你应该退后一步,问自己一个问题,你真正想要的行,行需要满足的条件。如果val_1 .. val_n来自数据库外部,请考虑首先将它们放入数据库。