【问题标题】:What are the performance implications of Oracle IN Clause with no joins?没有连接的 Oracle IN 子句对性能有何影响?
【发布时间】: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 */?

有没有创造性的方法来拉回数据,这样

  1. 我们执行最少的往返次数
  2. 我们读取的块数量最少(在逻辑 IO 级别?)
  3. 这会更快吗..
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


【解决方案1】:

如果您的表上的统计信息是准确的,那么当您在WHERE 子句中只有 1000 个硬编码元素时,优化器应该不太可能选择进行表扫描而不是使用主键索引。最好的方法是收集(或设置)对象的准确统计数据,因为这应该会导致好事自动发生,而不是为了解决不正确的统计数据而尝试做大量的体操。

如果我们假设统计信息的不准确程度会导致优化器认为表扫描比使用主键索引更有效,那么您可能会添加DYNAMIC_SAMPLING 提示,这将强制优化器在优化语句之前收集更准确的统计信息或 CARDINALITY 提示覆盖优化器的默认基数估计。这些都不需要知道有关可用索引的任何信息,只需要知道表别名(如果没有别名,则需要知道名称)。 DYNAMIC_SAMPLING 会是更安全、更健壮的方法,但会增加解析步骤的时间。

如果您在 IN 子句中使用可变数量的硬编码参数构建 SQL 语句,您可能会因为使用不可共享的 SQL 淹没共享池和迫使数据库花费大量时间分别对每个变体进行硬解析。如果您创建一个可以解析一次的可共享 SQL 语句,效率会高得多。根据您的 IN 子句值的来源,这可能类似于

SELECT *
  FROM table_name
 WHERE primary_key IN (SELECT primary_key
                         FROM global_temporary_table);

SELECT *
  FROM table_name
 WHERE primary_key IN (SELECT primary_key
                         FROM TABLE( nested_table ));

SELECT *
  FROM table_name
 WHERE primary_key IN (SELECT primary_key
                         FROM some_other_source);

如果您只使用一条可共享的 SQL 语句,那么除了避免不断地重新解析语句的成本之外,您还有许多选项可以强制执行不涉及修改语句的特定计划SQL 语句。不同版本的 Oracle 对计划稳定性有不同的选择 -- 有 stored outlinesSQL plan managementSQL profiles 以及其他技术,具体取决于您的版本。您可以使用这些来强制执行特定 SQL 语句的特定计划。但是,如果您不断生成必须重新解析的新 SQL 语句,那么使用这些技术将变得非常困难。

【讨论】:

  • 本主题很好地反映了不同查询设计和模式的成本。有时,经验法则只是一个路标,而不是严格的执行规则。
猜你喜欢
  • 2011-06-24
  • 2013-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-06
  • 2015-03-04
  • 1970-01-01
  • 2010-09-13
相关资源
最近更新 更多