SELECT ID 存在于第二个表中的行的最有效方法

2024-03-07

我希望从一个表中选择 ID 存在于第二个表中的所有记录。

以下两个查询返回正确的结果:

Query 1:

SELECT *
FROM Table1 t1
WHERE EXISTS (SELECT 1 FROM Table2 t2 WHERE t1.ID = t2.ID)

Query 2:

SELECT *
FROM Table1 t1
WHERE t1.ID IN (SELECT t2.ID FROM Table2 t2)

这些查询之一是否比另一个更有效?我应该使用其中一种而不是另一种吗?还有第三种我没有想到的更有效的方法吗?


Summary:

IN 和 EXISTS 在所有场景中执行类似。以下是用于验证的参数。

执行成本、时间:
两者相同,优化器产生相同的计划。
内存授予:
两个查询相同
Cpu 时间,逻辑读取:
尽管读取相同,但 Exists 在 CPU 时间方面似乎比 IN 略胜一筹。

我使用下面的测试数据集运行每个查询 10 次。

  1. 非常大的子查询结果集(100000 行)
  2. 重复行
  3. 空行

对于上述所有场景,IN and EXISTS以相同的方式执行。

一些关于性能V3数据库 http://tsql.solidq.com/resources/用于测试。 20000 个客户有 1000000 个订单,因此每个客户在订单表中随机重复(范围为 10 到 100)。

执行成本、时间:
下面是两个查询运行的屏幕截图。观察每个查询的相对成本。

内存成本:
两个查询的内存授予也是相同的..我强制 MDOP 1 以免将它们溢出到 TEMPDB..

CPU 时间,读取:

对于存在:

Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Customers'. Scan count 1, logical reads 109, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Orders'. Scan count 1, logical reads 3855, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

 SQL Server Execution Times:
   CPU time = 469 ms,  elapsed time = 595 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

For IN:

(20000 row(s) affected)
Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Customers'. Scan count 1, logical reads 109, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Orders'. Scan count 1, logical reads 3855, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

 SQL Server Execution Times:
   CPU time = 547 ms,  elapsed time = 669 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

在每种情况下,优化器都足够聪明,可以重新排列查询。

我倾向于使用EXISTS只是(我的意见)。一种使用案例EXISTS当您不想返回第二个表结果集时。

根据马丁·史密斯的询问更新:

我运行了以下查询,以找到从第一个表中获取第二个表中存在引用的行的最有效方法。

SELECT DISTINCT c.*
FROM Customers c
JOIN Orders o ON o.custid = c.custid   

SELECT c.*
FROM Customers c
INNER JOIN (SELECT DISTINCT custid FROM Orders) AS o ON o.custid = c.custid

SELECT *
FROM Customers C
WHERE EXISTS(SELECT 1 FROM Orders o WHERE o.custid = c.custid)

SELECT *
FROM Customers c
WHERE custid IN (SELECT custid FROM Orders)

除第二个查询外,上述所有查询都具有相同的成本INNER JOIN,其余计划相同。

内存授予:
这个查询

SELECT DISTINCT c.*
FROM Customers c
JOIN Orders o ON o.custid = c.custid 

所需的内存授予

这个查询

SELECT c.*
FROM Customers c
INNER JOIN (SELECT DISTINCT custid FROM Orders) AS o ON o.custid = c.custid 

所需的内存授予..

CPU 时间,读取:
对于查询:

SELECT DISTINCT c.*
FROM Customers c
JOIN Orders o ON o.custid = c.custid   

(20000 row(s) affected)
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Workfile'. Scan count 48, logical reads 1344, physical reads 96, read-ahead reads 1248, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Orders'. Scan count 5, logical reads 3929, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Customers'. Scan count 5, logical reads 322, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 1453 ms,  elapsed time = 781 ms.

对于查询:

SELECT c.*
FROM Customers c
INNER JOIN (SELECT DISTINCT custid FROM Orders) AS o ON o.custid = c.custid

(20000 row(s) affected)
Table 'Customers'. Scan count 5, logical reads 322, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Workfile'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Orders'. Scan count 5, logical reads 3929, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 1499 ms,  elapsed time = 403 ms.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SELECT ID 存在于第二个表中的行的最有效方法 的相关文章

  • 合并sql中的列

    我正在使用 SQL Server 2017 有一个存储过程 其中我有一个带有连接的简单选择 例如 SELECT p legacyKey AS JobNumber p Name AS JobName G Label AS DesignStat
  • SQL 查询将文本数据存储在 Varbinary(max) 中

    有没有办法让 varbinary 在 SQL Server 中接受文本数据 这是我的情况 我有相当大量的 XML 我计划以 压缩 格式存储它们 这意味着 Varbinary 但是 当我进行调试时 我希望能够翻转配置开关并以纯文本形式存储 以
  • 从 PL/SQL 调用 shell 脚本,但 shell 以 grid 用户而非 oracle 身份执行

    我正在尝试使用 Runtime getRuntime exec 从 Oracle 数据库内部执行 shell 脚本 在 Red Hat 5 5 上运行的 Oracle 11 2 0 4 EE CREATE OR REPLACE proced
  • RANK() OVER PARTITION 并重置 RANK

    如何获得在分区更改时重新启动的 RANK 我有这张表 ID Date Value 1 2015 01 01 1 2 2015 01 02 1
  • 如何将事物的组合映射到关系数据库?

    我有一个表 其记录代表某些对象 为了简单起见 我假设该表只有一列 这是唯一的ObjectId 现在我需要一种方法来存储该表中的对象组合 组合必须是唯一的 但可以是任意长度 例如 如果我有ObjectIds 1 2 3 4 我想存储以下组合
  • 当我使用可变参数而不是常量参数时,为什么我的内联表 UDF 慢得多?

    我有一个表值内联 UDF 我想过滤该 UDF 的结果以获得一个特定值 当我使用常量参数指定过滤器时 一切都很好 并且性能几乎是瞬时的 当我使用可变参数指定过滤器时 它会花费明显更大的时间块 大约是逻辑读取的 500 倍和持续时间的 20 倍
  • Docker 中的 Web api 无法连接到主机上的 SQL Server,并出现登录前握手错误

    首先有一些类似的问题 但我已经尝试了我能找到的所有建议 但似乎没有任何效果 如果你能找到我没有提到的 请评论 我会尝试一下 概要是我正在尝试将 Docker 容器中的 NET Core 3 1 Web api 连接到主机上的 SQL Ser
  • 如何使用 SQL 通过表示多级订单的 varchar 字段正确排序?

    我不太喜欢数据库 我发现在查询上出现以下问题SQL服务器数据库旧的遗留应用程序的 我声明不幸的是我无法更改数据库结构 字段类型 这非常难看 我有以下情况 SELECT Sottocategoria IdSottocategoria IdCa
  • IIS7 上的 ASP.NET 应用程序 - iisreset 后启动速度非常慢

    我有一个在 Windows 2008 上的 IIS7 下运行的 ASP NET 3 5 网站 当我重新启动 IIS iisreset 然后点击一个页面时 初始启动非常慢 我在 Process Explorer 中看到以下活动 w3wp ex
  • 将 MSSQL 中用于 Web 制图的投影(Leaflet、Openlayer、OpenStreetMaps、GoogleAPI...)更改为 WSG48 或任何其他格式

    我在 MSSQL 服务器中有一些像这样的 WKT WKB 数据 并希望借助 leaflet Openlayer OpenStreetMaps 或 GoogleAPI 将它们显示在地图上 我的数据如下所示 POLYGON 1736946 09
  • 如何在 Spring Data 中选择不同的结果

    我在使用简单的 Spring Data 查询或 Query 或 QueryDSL 在 Spring Data 中构建查询时遇到问题 如何选择三列 研究 国家 登录 不同的行 并且查询结果将是用户对象类型的列表 Table User Id S
  • Pandas hub_table 更快的替代品

    我正在使用熊猫pivot table在大型数据集 1000 万行 6 列 上运行 由于执行时间至关重要 因此我尝试加快流程 目前 处理整个数据集大约需要 8 秒 这太慢了 我希望找到替代方案来提高速度 性能 我当前的 Pandas 数据透视
  • 如何最大限度地提高服务器性能?

    我一直在努力了解性能和可扩展性 并想知道开发人员 系统管理员正在做什么来提高他们的系统的效率 为了标准化答案 如果您能尽力回答以下任一问题 将会有所帮助 Profile Magazine publication on Joomla Jobs
  • 如何引用下一行的数据?

    我正在 PostgreSQL 9 2 中编写一个函数 对于股票价格和日期的表 我想计算每个条目较前一天的百分比变化 对于最早一天的数据 不会有前一天 因此该条目可以简单地为 Nil 我知道WITH声明可能不应该高于IF陈述 到目前为止 这就
  • ASP SQL Server 连接

  • 自动删除主键序列中的间隙

    我正在创建一个网页 该网页根据用户操作将数据存储到 MySQL 数据库中 数据库有很多行 行的主键是列 rowID 它只是按顺序对行进行编号 例如 1 2 3 4 用户可以选择删除行 问题是当用户删除最后一行以外的行时 rowID 中有一个
  • 红宝石接球和效率

    catch在 Ruby 中意味着跳出深度嵌套的代码 在 Java 中 例如用Java也可以达到同样的效果try catch用于处理异常 但它被认为是糟糕的解决方案 而且效率非常低 在 Ruby 中 我们有处理异常的方法begin raise
  • 如何用 kevent() 替换 select() 以获得更高的性能?

    来自Kqueue 维基百科页面 http en wikipedia org wiki Kqueue Kqueue 在内核和用户空间之间提供高效的输入和输出事件管道 因此 可以修改事件过滤器以及接收待处理事件 同时每次主事件循环迭代仅使用对
  • java库维护数据库结构

    我的应用程序一直在开发 所以偶尔 当版本升级时 需要创建 更改 删除一些表 修改一些数据等 通常需要执行一些sql代码 是否有一个 Java 库可用于使我的数据库结构保持最新 通过分析类似 db structure version 信息并执
  • 标量子查询包含多行

    我正在使用 H2 数据库并想要移动一些数据 为此 我创建了以下查询 UPDATE CUSTOMER SET EMAIL SELECT service EMAIL FROM CUSTOMER SERVICE AS service INNER

随机推荐

  • 在Python中将外部函数分配给类变量

    我试图将其他地方定义的函数分配给类变量 以便稍后可以在实例的方法之一中调用它 如下所示 from module import my func class Bar object func my func def run self self f
  • CLR是虚拟机吗?

    我读过一本提到 net 的书CLR 作为虚拟机 任何人都可以证明这一点吗 为什么我们在某些开发平台上需要虚拟机的概念 是否有可能开发一个完全面向对象且像 net一样强大的本机框架 没有虚拟机的框架 将 CLR 称为虚拟机的书是 专业 Net
  • 如何在 Bash 中将文件名中的填充数字清零?

    使用 Bash 重命名以下形式的文件的最佳方法是什么 foo1 foo2 foo1300 fooN 使用零填充的文件名 foo00001 foo00002 foo01300 fooN 这不是纯粹的 bash 但是使用 Perl 版本更容易r
  • 如何在 Java 中验证公钥和私钥对

    有没有一种方法可以在 java 中验证给定的私钥 例如某个 key 文件 是否与某个使用 RSA 算法的某个 pub 文件匹配的公钥 您可以通过以下方式验证密钥对是否匹配 创建一个挑战 足够长度的随机字节序列 signing的挑战私钥 验证
  • Blackberry:读取项目中打包的文本文件(更快)

    我尝试过这种方法 但对于稍大的文本文件来说 它确实很慢 有谁知道阅读项目中包含的纯文本文件的更好方法 有没有办法使用 FileConnection 使用信息组合找出答案 IOUtilities streamToBytes is 直接在输入流
  • 当涉及部分操作时,不会调用 PerformBatchUpdates 完成处理程序

    到目前为止 这里的代码片段几乎适用于NSFetchedResultsController UICollectionView 根据所提供的信息 https developer apple com videos play wwdc2018 22
  • JWT 身份验证,无需在每个请求上获取用户详细信息

    我正在 Spring Security 中实现 JWT 身份验证 我有预定义的角色 例如 普通用户 管理员等 我有以下令牌有效负载 sub nick iat
  • 优化 R 中的正则表达式以进行子字符串提取

    我对之前的答案有一个后续问题 可以在这里找到 R 中拆分不均匀字符串 可变子字符串和分隔符 https stackoverflow com q 69921210 3832970 总之 我想提取遵循以下模式的字符串中的粗体文本 sp Q2UV
  • beanstalkd 的统计数据/监视器/检查器

    有谁知道有一个可以监控 beanstalkd 队列的应用程序吗 我正在寻找一些可以显示管道和工作统计信息并允许您检查详细信息的东西 我对语言 平台并不是很挑剔 只是想在编写自己的语言 平台之前知道是否有可用的东西 所有这些以及至少另外两个都
  • Selenium chrome 驱动程序袜子代理配置

    我在为 Chrome 驱动程序设置袜子代理时遇到问题 Proxy proxy new Proxy proxy setProxyType Proxy ProxyType MANUAL proxy setAutodetect false pro
  • 为什么我无法以种子用户身份登录?

    我正在开发一个新的 ASP NET MVC 项目 使用存储在数据库中的个人帐户进行身份验证 这是我的类 每次测试时都会使用示例数据为数据库播种 public class DevelopmentInitializer DropCreateDa
  • getMinutes() 0-9 - 如何显示两位数字?

    var date 2012 01 18T16 03 var date new Date date console log date getMinutes console log date getMinutes length 这将返回 3 如
  • OS X 上的输入管理器

    我想知道 InputManager 是否仍然是 Leopard 的一部分 是否有一个很好的例子可以告诉我它有什么用处 InputManagers 在 Leopard 上仍然可用 except 它们需要位于本地域中 Library Input
  • 派生类不会重写具有不同签名的虚函数

    我有一个派生类 我希望其中一个函数覆盖其在基类中的版本 但具有不同的签名 简单的例子 include stdio h bool use foo false class Foo public virtual int func double x
  • 量角器:按住 Ctrl 单击

    我正在尝试使用 ctrl 单击连续元素来选择页面上的多个元素 此功能在手动完成时工作正常 但我在使用量角器进行自动化时遇到了一些麻烦 这是我的 ptor 函数 this selectElements function names for v
  • 预期块结束 YAML 错误

    将此 YAML 文件粘贴到在线 yaml 解析器中时 我收到预期的块结束错误 ADDATTEMPTING Tentative d ajout ATTEMPTINGTOGIVE Tenter de donner ATTEMPTINGTOSET
  • 解析包含尾随逗号的“JSON”

    有没有可以处理尾随逗号的 Python JSON 解析器 我正在使用来自外部源的 JSON 并且无法控制它 获取 PyYAML JSON 是 YAML 的子集 因此 YAML 解析器应该解析大多数 JSON YAML 的语法允许序列中尾随逗
  • java spring MappingJacksonJsonView 没有在 mongodb ObjectId 上执行 toString

    我在 SpringMVC 应用程序中使用 MappingJacksonJsonView 从控制器渲染 JSON 我希望对象中的 ObjectId 呈现为 toString 但它会将 ObjectId 序列化为其各个部分 它在我的 Veloc
  • 错误:预期类型为 com.MyApp.Main 的接收者,但得到了 java.lang.Class

    我试图将一个类导入到 MVEL 的实现中 但出现以下错误 错误 预期接收者类型为 com MyApp Main 但得到了 java lang Class 这是设置 MVEL 的方法 public void runCode final Str
  • SELECT ID 存在于第二个表中的行的最有效方法

    我希望从一个表中选择 ID 存在于第二个表中的所有记录 以下两个查询返回正确的结果 Query 1 SELECT FROM Table1 t1 WHERE EXISTS SELECT 1 FROM Table2 t2 WHERE t1 ID