【发布时间】:2014-05-12 22:27:57
【问题描述】:
我有一个这种形式的查询,它平均需要大约 100 个子句元素,并且在极少数情况下需要超过 1000 个元素。如果超过 1000 个元素,我们会将 in 子句分块到 1000 个(Oracle 最大值)。
SQL 格式为
SELECT * FROM tab WHERE PrimaryKeyID IN (1,2,3,4,5,...)
我从中选择的表非常庞大,并且包含的行数将比我的 in 子句中的多几百万行。我担心优化器可能会选择进行表扫描(我们的数据库没有最新的统计信息 - 是的 - 我知道......)
我是否可以通过提示强制使用主键 - 在不知道主键的索引名称的情况下,可能类似于 ... /*+ DO_NOT_TABLE_SCAN */?
有没有创造性的方法来拉回数据,这样
- 我们执行最少的往返次数
- 我们读取的块数量最少(在逻辑 IO 级别?)
- 这会更快吗..
SELECT * FROM tab WHERE PrimaryKeyID = 1 UNION SELECT * FROM tab WHERE PrimaryKeyID = 2 UNION SELECT * FROM tab WHERE PrimaryKeyID = 2 UNION ....
【问题讨论】:
-
+INDEX (tab)? YMMV。虽然,也许只是确保适当的统计数据并信任查询规划器..(规划器通常在认为它在 IO 成本方面“更好”时选择 FTS,因此强制使用索引可能会颠覆这一点) .另一种选择可能是通过 OPTIMIZER_INDEX_COST_ADJ 降低索引使用成本。再说一次,YMMV。
标签: sql performance oracle plsql sql-tuning