通过使用替换和长度检查来避免 SQL Not IN

2024-01-20

我遇到的情况是,我必须动态创建 SQL 字符串,并且我正在尝试尽可能使用参数和 sp_executesql,以便我可以重用查询计划。在进行大量在线阅读和个人经验中,我发现“NOT IN”和“INNER/LEFT JOIN”在基础(最左边)表很大(150 万行,大约 50 列)时执行缓慢且昂贵)。我还读到应避免使用任何类型的函数,因为它会减慢查询速度,所以我想知道哪个更糟糕?

我过去曾使用过这种解决方法,尽管我不确定这是最好的做法,以避免在项目列表中使用“NOT IN”,例如,当我传递 3 个字符串的列表时例如,使用管道分隔符(仅在元素之间):

LEN(@param1) = LEN(REPLACE(@param1, [col], '')) 

代替:

[col] NOT IN('ABD', 'RDF', 'TRM', 'HYP', 'UOE') 

...想象一下字符串列表的长度为 1 到大约 80 个可能的值,并且此方法也不适合参数化。

在这个例子中,我可以使用“=”来表示 NOT IN,并且我会使用传统的列表技术来表示 IN,或者 !=(如果这样更快的话),尽管我对此表示怀疑。这比使用 NOT IN 更快吗?

作为可能的第三种选择,如果我知道所有其他可能性(IN 可能性,列表可能长 80-95 倍)并通过它们,会怎样?这将在应用程序的业务层中完成,以减轻 SQL Server 的工作负载。对于查询计划重用来说,这不是一个很好的可能性,但如果它可以让一个大的令人讨厌的查询减少一两秒,那为什么不呢?

我还擅长 SQL CLR 函数创建。既然上面是字符串操作,那么 CLR 函数是最好的吗?

想法?

预先感谢您提供的任何和所有帮助/建议/等。


正如唐纳德·高德纳 (Donald Knuth) 经常被(错误地)引用的那样,“过早的优化是万恶之源”。
因此,首先,您确定如果您以最清晰、最简单的方式(写入和读取)编写代码,它的执行速度会很慢吗?如果没有,请在开始使用任何“聪明”的优化技巧之前检查一下。

如果代码速度很慢,请彻底检查查询计划。大多数时候,查询执行的时间比查询编译的时间长得多,因此通常您不必担心查询计划的重用。因此,构建最佳索引和/或表结构通常会比调整查询的构建方式提供更好的结果。

例如,我严重怀疑使用 LEN 和 REPLACE 的查询比 NOT IN 具有更好的性能 - 在任何一种情况下,都会扫描所有行并检查是否匹配。对于足够长的列表,MSSQL 优化器会自动创建一个临时表来优化相等比较。
更重要的是,这样的技巧往往会引入错误:比如说,如果 [col] = 'AB',您的示例将无法正常工作。

IN 查询通常比 NOT IN 更快,因为对于 IN 查询,仅检查部分行就足够了。该方法的效率取决于您是否能够足够快地获得正确的 IN 列表。

说到将可变长度列表传递到服务器,这里和其他地方有很多讨论。一般来说,您的选择是:

  • 表值参数(仅限 MSSQL 2008+),
  • 动态构建的 SQL(容易出错和/或不安全),
  • 临时表(适合长列表,对于短列表来说可能在写入和执行时间上有太多开销),
  • 分隔字符串(适用于“行为良好”值的简短列表 - 例如少数整数),
  • XML 参数(有些复杂,但效果很好 - 如果您使用良好的 XML 库并且不“手动”构造复杂的 XML 文本)。

这是一个article http://www.sommarskog.se/arrays-in-sql-2005.html对这些技术和其他一些技术有很好的概述。

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

通过使用替换和长度检查来避免 SQL Not IN 的相关文章

  • 单个对象的 Monogame XNA 变换矩阵?

    我读过一些解释 XNA Monogame 变换矩阵的教程 问题是这些矩阵应用于 SpriteBatch Begin matrix 这意味着所有 Draw 代码都将被转换 如何将变换矩阵应用于单个可绘制对象 就我而言 我想转换滚动背景 使其自
  • 在 C 中初始化变量

    我知道有时如果你不初始化int 如果打印整数 您将得到一个随机数 但将所有内容初始化为零似乎有点愚蠢 我问这个问题是因为我正在评论我的 C 项目 而且我对缩进非常直接 并且它可以完全编译 90 90 谢谢 Stackoverflow 但我想
  • 标准化 UTF-8 到底是什么?

    The 重症监护室项目 http userguide icu project org transforms normalization 现在也有一个PHP库 http us php net manual en class normalize
  • 具有交替类型的可变参数模板参数包

    我想知道是否可以使用参数包捕获交替参数模式 例如 template
  • 我可以从 SQL Server 读取元数据来了解最后更改的行/表吗?

    我们有一个数据库hundreds的桌子 有没有某种metaSQL Server 中的数据源 我可以以编程方式查询以获取名称最后更改表和行 或者我们是否需要实施这个我们自己每个表中的字段称为上次更改日期时间 etc 就查明表最后一次修改的时间
  • Qt - ubuntu中的串口名称

    我在 Ubuntu 上查找串行端口名称时遇到问题 如您所知 为了在 Windows 上读取串口 我们可以使用以下代码 serial gt setPortName com3 但是当我在 Ubuntu 上编译这段代码时 我无法使用这段代码 se
  • 如何在 32 位或 64 位配置中以编程方式运行任何 CPU .NET 可执行文件?

    我有一个可在 32 位和 64 位处理器上运行的 C 应用程序 我试图枚举给定系统上所有进程的模块 当尝试从 64 位应用程序枚举 32 位进程模块时 这会出现问题 Windows 或 NET 禁止它 我认为如果我可以从应用程序内部重新启动
  • 如何在 Xaml 文本中添加电子邮件链接?

    我在 Windows Phone 8 应用程序中有一些大文本 我希望其中有电子邮件链接 例如 mailto 功能 这是代码的一部分
  • C# 中的合并运算符?

    我想我记得看到过类似的东西 三元运算符 http msdn microsoft com en us library ty67wk28 28VS 80 29 aspx在 C 中 它只有两部分 如果变量值不为空 则返回变量值 如果为空 则返回默
  • 为什么 std::strstream 被弃用?

    我最近发现std strstream已被弃用 取而代之的是std stringstream 我已经有一段时间没有使用它了 但它做了我当时需要做的事情 所以很惊讶听到它的弃用 我的问题是为什么做出这个决定 有什么好处std stringstr
  • 动态添加 ASP.Net 控件

    我有一个存储过程 它根据数据库中存储的记录数返回多行 现在我想有一种方法来创建 div 带有包含该行值的控件的标记 如果从数据库返回 10 行 则 10 div 必须创建标签 我有下面的代码来从数据库中获取结果 但我不知道如何从这里继续 S
  • 如何在非控制台应用程序中查看 cout 输出?

    输出到调试窗口似乎相当繁琐 我在哪里可以找到cout如果我正在编写非控制台信息 则输出 Like double i a b cout lt lt b lt lt endl I want to check out whether b is z
  • C++ 函数重载类似转换

    我收到一个错误 指出两个重载具有相似的转换 我尝试了太多的事情 但没有任何帮助 这是那段代码 CString GetInput int numberOfInput BOOL clearBuffer FALSE UINT timeout IN
  • 按 Esc 按键关闭 Ajax Modal 弹出窗口

    我已经使用 Ajax 显示了一个面板弹出窗口 我要做的是当用户按 Esc 键时关闭该窗口 这可能吗 如果有人知道这一点或以前做过这一点 请帮助我 Thanks 通过以下链接 您可以通过按退出按钮轻松关闭窗口 http www codepro
  • 不同类型指针之间的减法[重复]

    这个问题在这里已经有答案了 我试图找到两个变量之间的内存距离 具体来说 我需要找到 char 数组和 int 之间的距离 char data 5 int a 0 printf p n p n data 5 a long int distan
  • 调用堆栈中的“外部代码”是什么意思?

    我在 Visual Studio 中调用一个方法 并尝试通过检查调用堆栈来调试它 其中一些行标记为 外部代码 这到底是什么意思 方法来自 dll已被处决 外部代码 意味着该dll没有可用的调试信息 你能做的就是在Call Stack窗口中单
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类
  • 我是否需要在外键上指定 ON DELETE NO ACTION?

    我有以下与 SQL Server 2012 一起使用的 DDL CREATE TABLE Subject SubjectId INT IDENTITY 1 1 NOT NULL Name NVARCHAR 50 Not NULL CONST
  • 如何部署“SQL Server Express + EF”应用程序

    这是我第一次部署使用 SQL Server Express 数据库的应用程序 我首先使用实体 框架模型来联系数据库 我使用 Install Shield 创建了一个安装向导来安装应用程序 这些是我在目标计算机中安装应用程序所执行的步骤 安装
  • 从列表中选择项目以求和

    我有一个包含数值的项目列表 我需要使用这些项目求和 我需要你的帮助来构建这样的算法 下面是一个用 C 编写的示例 描述了我的问题 int sum 21 List

随机推荐