在调用 UDF 本身时进行索引搜索,在将 UDF 包装在 sp 中时进行索引扫描

Posted

技术标签:

【中文标题】在调用 UDF 本身时进行索引搜索,在将 UDF 包装在 sp 中时进行索引扫描【英文标题】:index seek while calling the UDF itself, index scan while wrapping the UDF in sp 【发布时间】:2010-10-08 01:16:07 【问题描述】:

我有一个 UDF 可以完成大部分连接,当我运行它时,它读取了大约 100-150 页(来自 sql profiler),但是如果我将这个 UDF 包装在 sp 中,那么 sp 将读取大约 243287 页。

此外,UDF 本身执行索引查找,但 sp 对搜索到的列之一执行索引扫描。

谁能给点建议?

【问题讨论】:

您需要更具体地说明您的要求。 好的..让我再试一次..我有 UDF(比如 pullCustomerUDF),它需要 3 个参数。如果我使用 select 语句调用 UDF(例如 select * from pullCustomerUDF('param1', 'parm2', 'param3'),它可以正常读取 110 页(在 100 微秒内)。但是,如果我在其中包含 select 语句一个存储过程并执行存储过程,它将在 5-7 秒内读取 243287 个页面。有什么想法吗? 还请注意,存储过程中不包含除 select 语句之外的任何其他代码! 好的,找到了问题,但我无法解释自己的原因。我有这样的比较:(custid = @param1 OR @param1 is null)当我删除“is null”并变成这样时:(custid = @param1)然后存储的proc现在执行得如此之快。谁能解释一下?我也 SET ANSI_NULLS ON 但没有运气 有趣的是,您一定把查询优化器弄糊涂了,可能是按顺序读取表。 【参考方案1】:

根据您关于(custid = @param1 OR @param1 is null)(custid = @param1) 的cmets,我认为Gail Shaw 在Catch-all queries 上的博文将提供一些关于您在此处看到的内容的见解。基本上,我认为您正在为@param1 is null 案例缓存一个执行计划,然后当您传入一个真实的@param1 时执行计划会很差。

【讨论】:

我如何刷新执行计划。我还尝试使用 RECOMPILE 选项创建存储过程,但它没有修复执行计划 重新编译不会解决这个问题。 SQL 会为这种查询模式生成错误的计划。请参阅我的博文(上面引用过),或更改查询以使该参数不再是可选的。

以上是关于在调用 UDF 本身时进行索引搜索,在将 UDF 包装在 sp 中时进行索引扫描的主要内容,如果未能解决你的问题,请参考以下文章

Pyspark:从 Struct 中识别 arrayType 列并调用 udf 将数组转换为字符串

Pyspark SIZE 函数本身可以工作,但在 UDF 中它没有 [关闭]

如何使用调用 UDF 的 Python 脚本来使用 BigQuery API

UDF函数,hive调用java包简单方法

Hive自定义UDF函数

如何调用在另一个 UDF 中返回数组的 UDF?