让我们从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
是无关紧要的,所以我们再次将全表扫描作为唯一的访问路径。
那么我们希望的最佳执行计划是什么?就像是:
- T的全表扫描
- 过滤 S 的 2500+ 个值
- D的全表扫描
- TS 和 D.D1 的哈希连接
...除了那些通配符将意味着嵌套循环操作而不是哈希连接。
最后让我们考虑一下这个声明:
“解决请求的时间大约是五分钟”
调整中的单个帖子重要的是对经过的时间有一个合理的期望。在这种情况下,五分钟可能代表非常缓慢的响应或非常快速的响应。谁能告诉?我们当然不能。只有 OP 可以,因为只有他们才能访问数据并因此有能力回答这些问题:
- 列的平均长度是
D1
多少D2
?
- 表中有多少行
D
?
- 什么是合理的阅读它们?
- 列的平均长度是
S
多少?
- 表中有多少行
T
?
- 什么是合理的阅读它们?
T
where有多少行S
匹配 '%val_1%' 到 '%val_n%' ?
- 有多少行
D
匹配D1
'%val_1%' 到 '%val_n%'?
- 什么是匹配它们的合理时间?
- 显示 D2 的所有相关值的合理时间是多少?