当前位置: 首页 > 面试题库 >

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

时衡虑
2023-03-14
问题内容

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

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

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

代替:

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

…想象一下,字符串列表的长度为1到大约80个可能的值,而且这种方法也无法使其自我参数化。

在此示例中,我可以对NOT NOT使用“ =”,对我的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列表。

说到将可变长度列表传递到服务器,这里有关于SO和其他地方的许多讨论。通常,您可以选择:

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

这是一篇很好地概述了这些技术的文章,还有其他一些文章。



 类似资料:
  • 我想知道是否有可能在Java中“避免”空检查,以下面的代码为例: 它必须检查4次,否则代码将失败。 是否可以将语句转换为只有在没有NullPointerException时才执行的一行式语句?当出现异常时,该行应该被忽略。 这里我不是在谈论一个通用的语言特性,我是在谈论一个只有当您明确决定这样做时才会上交的特性。 例如:将是建议代码的一个片段。 在Java可能发生这样的事情吗? 如果不可能的话,在

  • 问题内容: 我有一个数据框如下。 我正在阅读一个句子,并想用上面定义的同义词替换该句子中的单词。这是我的代码: 上面的代码将输入句子标记化。我想实现以下输出: 进 : 出 : 但是我得到的输出是 出 : 如果我跳过该函数,那么我的输出将没有问题,并且将分成单个单词。我试图了解我在函数中做错了什么。另外,请告知是否有更好的解决方案。 问题答案: 我会利用Pandas / NumPy索引。由于您的同义

  • null本身不是对象,也不是Objcet的实例 问题: null代表不确定的对象, 是一个很模糊的概念, 容易产生二义性 Map.get(key)若返回value值为null,其代表的含义可能是该键指向的value值是null,亦或者该键在map中并不存在 优点: 从内存消耗和效率方面,null更加廉价 优化: Optional com.google.common.base.Optional Op

  • 我有如下所示的JSON 我将文件读成字符串并创建一个JSONObject,如下所示 然而,我认为我可以用try catch将语句括起来 请建议在这种情况下是否有任何合理的理由放一个长的if条件,而不是仅仅try-catch-log然后继续。 您还可以分享使用JSONException在此上下文中是否有任何“优点”吗?

  • 如果我在文件已经存在的同一个容器中上传azure blob上的文件,它正在覆盖文件,如何避免覆盖相同的文件?下面我提到的场景... 步骤1-将文件“abc.jpg”上传到azure上名为“filecontainer”的容器中 第二步-一旦它被上传,尝试上传一些不同的同名文件到同一个容器 输出 - 它将用最新上传的文件覆盖现有文件 我的要求-我想避免这种覆盖,因为不同的人可能会将具有相同名称的文件上

  • 有没有可能编写这样的内容,并且避免检查元素是否为空,集合是否为空: 我找到了这样的东西http://winterbe.com/posts/2015/03/15/avid-null-check-in-/ 基本上,我想要实现的是避免层次结构中如果带有多个检查天气对象的语句为null或集合为空。我在上面的文章中读到,这是可能的,可选的“空检查在引擎盖下自动处理。” 如果已经有了一些解决方案,很抱歉复制,