通过使用替换和长度检查来避免 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 的相关文章

  • java中如何重新初始化int数组

    class PassingRefByVal static void Change int pArray pArray 0 888 This change affects the original element pArray new int
  • 无法注册时间触发的后台任务

    对于 Windows 8 应用程序 在 C Xaml 中 我尝试注册后台任务 很难说 但我想我的后台任务已正确注册 但是当我单击调试位置工具栏上的后台任务名称时 我的应用程序停止工作 没有任何消息 我查看了事件查看器上的日志 得到 具有入口
  • Task.Run 作为反模式?

    我正在将 SQLite NET PCL 库用于我的 WinRT 项目SQliteAsyncConnection类 它提供经典的异步版本SQLiteConnection方法 然而 就该项目而言Github页面 https github com
  • 在 C# 中,如何根据在 gridview 行中单击的按钮引用特定产品记录

    我有一个显示产品网格视图的页面 该表内有一列 其中有一个名为 详细信息 的超链接 我想这样做 以便如果用户单击该特定产品的详细信息单元格 将打开一个新页面 提供有关该产品的更多信息 我不确定如何确定哪个Product记录链接的详细信息以及我
  • Eigen 和 OpenMP:由于错误共享和线程开销而没有并行化

    系统规格 Intel Xeon E7 v3 处理器 4 插槽 16 核 插槽 2 线程 核心 Eigen 系列和 C 的使用 以下是代码片段的串行实现 Eigen VectorXd get Row const int j const int
  • C++中判断unicode字符是全角还是半角

    我正在编写一个终端 控制台 应用程序 该应用程序应该包装任意 unicode 文本 终端通常使用等宽 固定宽度 字体 因此要换行文本 只需计算字符数并观察单词是否适合一行并采取相应的操作 问题是 Unicode 表中的全角字符在终端中占用了
  • 从网页运行 ClickOnce 应用程序,无需用户操作

    我们有一个基于 Java 的 Web 应用程序以及用 C 编写的相同应用程序 如果 java 检查器发现客户端计算机上没有安装 Java 则应该运行该应用程序 这个想法是运行 C 单击一次 http en wikipedia org wik
  • 已发布的 .Net Core 应用程序警告安装 .Net Core,但它已安装

    我制作了一个 WPF 和控制台应用程序 供某人在我无法访问的私人服务器上使用 我使用 Visual Studio 2019 的内置 发布向导 来创建依赖于框架的单文件应用程序 当该人打开 WPF 应用程序时 他们会看到标准警告 他们单击 是
  • 在 C 中使用枚举而不是 #defines 作为编译时常量是否合理?

    在 C 工作了一段时间后 我将回到 C 开发领域 我已经意识到 在不必要的时候应该避免使用宏 以便让编译器在编译时为您做更多的工作 因此 对于常量值 在 C 中我将使用静态 const 变量或 C 11 枚举类来实现良好的作用域 在 C 中
  • 将 Word 转换为 PDF - 禁用“保存”对话框

    我有一个用 C 编写的 Word 到 PDF 转换器 除了一件事之外 它工作得很好 有时 在某些 Word 文件上 后台会出现一条消息保存源文件中的更改 gt 是 否 取消 但我没有对源文件进行任何更改 我只想从 Word 文件创建 PDF
  • C++ 对象用 new 创建,用 free() 销毁;这有多糟糕?

    我正在修改一个相对较大的 C 程序 不幸的是 并不总是清楚我之前的人使用的是 C 还是 C 语法 这是在一所大学的电气工程系 我们 EE 总是想用 C 来做所有事情 不幸的是 在这种情况下 人们实际上可以逃脱惩罚 但是 如果有人创建一个对象
  • 使动态创建的链接标签在 Winforms 中可点击

    我正在制作一个程序 允许用户单击由动态链接标签创建的公司名称 在我想知道如何做到这一点之前 我从未在 C 中使用过链接标签 可为特定用户生成的业务数量各不相同 因此每个用户的链接标签数量并不相同 然后我想捕获业务 ID 以进行 Json 调
  • C++:为什么 numeric_limits 对它不知道的类型起作用?

    我创建了自己的类型 没有任何比较器 也没有专门化std numeric limits 尽管如此 由于某种原因 std numeric limits
  • Visual Studio '17 未在参考管理器中显示程序集

    我遇到的问题是 我似乎无法弄清楚如何添加对某些解决方案的引用 在我从 Visual Studio 17 开始的大多数解决方案中 我在解决方案资源管理器中看到 引用 但例如对于 asp net core web api 我得到 依赖项 每当解
  • 了解 Lambda 表达式和委托 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我已经尝试解决这个问题很长一段时间了 阅读在线博客和文章 但到目前为止还没有成功 什么是代表 什么是 Lambda 表达式 两者的优点
  • 在 Win32 控制台应用程序中设置光标位置

    如何在 Win32 控制台应用程序中设置光标位置 最好 我想避免制作句柄并使用 Windows 控制台功能 我花了整个早上沿着那条黑暗的小巷跑 它产生的问题比它解决的问题还要多 我似乎记得当我在大学时使用 stdio 做这件事相对简单 但我
  • 在 System.Type 上使用条件断点时出错

    这是函数 public void Init System Type Type this Type Type BuildFieldAttributes BuildDataColumns FieldAttributes 我在第一行设置了一个断点
  • 是否允许全局静态标识符以单个 _ 开头?

    换句话说 可能static 文件范围 全局变量恰好以一个下划线开头 而不会产生与 C 实现发生名称冲突的可能性 https www gnu org software libc manual html node Reserved Names
  • MySqlConnectionStringBuilder - 使用证书连接

    我正在尝试连接到 Google Cloud Sql 这是一个 MySql 解决方案 我能够使用 MySql Workbench 进行连接 我如何使用 C 连接MySqlConnectionStringBuilder 我找不到提供这三个证书的
  • 如何在 C 中将 char 连接到 char* ?

    我怎样才能前置char c to char myChar 我有c值为 A and myChar值为 LL 我怎样才能前置c to myChar使 ALL 这应该有效 include

随机推荐