【问题标题】:Performance issue with IN clauseIN 子句的性能问题
【发布时间】:2019-11-19 22:20:23
【问题描述】:

我对在 sql 查询中使用 IN 子句有疑问,以下哪项提供更好的性能

SELECT * FROM emp WHERE deptno IN (10,20)

WITH dep AS (SELECT 10 deptno FROM DUAL UNION ALL
         SELECT 20 deptno FROM DUAL)
SELECT * FROM EMP e
WHERE EXISTS (SELECT 1 FROM dep WHERE dep.deptno=e.deptno);

我正在寻找哪个会提供更好的性能

【问题讨论】:

  • 通常,连接可以比IN 更好地优化,但您只需要逐个分析。对于您的示例,性能可能没有差异,但第一个选择使您的意图显而易见并且更易于维护。我不了解 Oracle,但是在 SQL Server 中,如果 emp 很大并且在 deptno 上有一个过滤索引,那么第一个可能会更快
  • 您的标题是“IN 子句的性能问题”。如果您有要解决的性能问题,请发布查询计划
  • 我认为几乎可以肯定,选项 1 赢得了我能想到的所有比较,尤其是可读性、可维护性和性能。我的问题是你为什么想做不同的事情?它已经勾选了所有方框。选项 2 是火车残骸。即使它确实“表现得更好”(这是不可能的),我也不会这样做,因为我不想在我的项目中使用火车残骸代码。
  • 感谢 Bohemian 和 Nick,实际上我在这里试图就查询的性能发表意见。可维护性和可读性是次要部分。
  • 基本上......当您在被搜索的列上有索引并且数据具有高基数(许多不同的唯一值)时,任何一种方式都可以。如果您有一个绝对庞大的列表,那么将其放入表中并为其编制索引可能会更快。

标签: oracle database-performance query-performance


【解决方案1】:

“In 子句”将是更好的选择,因为在另一个示例中,优化器无法弄清楚如何连接这两个表,因此它会扫描所有 emp 表并查看特定记录是否符合您的条件。我已经在巨大的表(超过百万行)上检查了这个,查询计划非常不同。当然,我假设您在 deptno 列上有索引。如果没有它,这两种解决方案都需要对 emp 表进行全表扫描。

【讨论】:

  • 谢谢。澄清理解
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-01
  • 2013-02-26
  • 2017-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-03
相关资源
最近更新 更多