参数的性能不如硬编码值

2024-05-26

我有一个执行得很糟糕的存储过程。当我声明一个变量时,设置它的值,然后在 where 子句中使用它,该语句需要一个多小时才能运行。当我对 where 子句中的变量进行硬编码时,它的运行时间不到一秒。

我开始通过执行计划来查找问题所在。看起来当我尝试向它传递一些声明的变量时,执行计划会创建一些哈希匹配,因为它从使用 UNION 和公共表表达式的视图中选择值。



/*************   Begin of Stored Procedure ***************/
CREATE PROCEDURE GetFruit
  @ColorId bigint,
  @SeasionId bigint
WITH RECOMPILE
AS
BEGIN

SELECT
    A.Name
FROM
    [Apple_View] A   /* This is the view down below */
    INNER JOIN [Fruit] F
        ON ( F.ColorId = @ColorId
            AND A.FruitId = F.FruitId)          
WHERE
    (A.ColorId = @ColorId
    AND 
    A.SeasonId = @SeasonId)

END
/************* End of Stored Procedure   ***************/

/************* Begin of View   ***************/
WITH Fruits (FruitId, ColorId, SeasonId) AS
(
    -- Anchor member
    SELECT
        F.FruitId
        ,F.ColorId
        ,F.SeasonId
    FROM
        ((  
            SELECT DISTINCT
                EF.FruitId
                ,EF.ColorId
                ,EF.SeasonId
                ,EF.ParentFruitId
            FROM
                ExoticFruit EF
                INNER JOIN Fruit FR
                    ON FR.FruitId = EF.FruitId
        UNION
            SELECT DISTINCT
                SF.FruitId
                ,SF.ColorId
                ,SF.SeasonId
                ,SF.ParentFruitId               
            FROM
                StinkyFruit SF
                INNER JOIN Fruit FR
                    ON FR.FruitId = SF.FruitId
        UNION
            SELECT DISTINCT
                CF.FruitId
                ,CF.ColorId
                ,CF.SeasonId
                ,CF.ParentFruitId
            FROM
                CrazyFruit CF
                INNER JOIN Fruit FR
                    ON FR.FruitId = CF.FruitId

            )) f

    UNION ALL

    -- Recursive Parent Fruit
    SELECT 
        FS.FruitId
        ,FS.ColorId
        ,FS.SeasonId
        ,FS.ParentFruitId
    FROM
        Fruits FS
        INNER JOIN MasterFruit MF
            ON  MF.[ParentFruitId] = fs.[FruitId]
)

SELECT DISTINCT
    FS.FruitId
    ,FS.ColorId
    ,FS.SeasonId
    FROM
        Fruits FS

/************* End of View   ***************/


/* To Execute */
EXEC GetFruit 1,3
  

If I run the Stored Procedure using the set values it takes over an hour and here is the execution plan. With Variables

如果我运行删除 DECLARE 和 SET 值的存储过程,并将Where子句设置为以下语句,它将在不到一秒的时间内运行,这是执行计划:

WHERE(A.ColorId = 1 AND  A.SeasonId = 3)

请注意硬编码变量如何使用索引,而第一个变量使用哈希集。这是为什么?为什么 where 子句中的硬编码值与声明的变量不同?

--------这就是在@user1166147的帮助下最终执行的--------

我将存储过程更改为使用 sp_executesql。



CREATE PROCEDURE GetFruit
  @ColorId bigint,
  @SeasionId bigint
WITH RECOMPILE
AS
BEGIN

DECLARE @SelectString nvarchar(max)

SET @SelectString = N'SELECT
    A.Name
FROM
    [Apple_View] A   /* This is the view down below */
    INNER JOIN [Fruit] F
        ON ( F.ColorId = @ColorId
            AND A.FruitId = F.FruitId)          
WHERE
    (A.ColorId = ' + CONVERT(NVARCHAR(MAX), @ColorId) + '
    AND 
    A.SeasonId = ' + CONVERT(NVARCHAR(MAX), @SeasonId) + ')'

EXEC sp_executesql @SelectString

END
  

编辑摘要根据 Damien_The_Un believer 的要求

目标是在创建计划之前获取有关 SQL 变量值的最佳/最多信息,通常参数嗅探就是这样做的。在这种情况下,参数嗅探被“禁用”可能是有原因的。如果没有看到实际代码的更好表示,我们就无法真正说出解决方案是什么或问题存在的原因。请尝试以下操作,强制受影响的区域使用实际值生成计划。

*包含更多细节的长版 *

这是您实际的存储过程吗?你的参数有默认值吗?如果有,它们是什么?

参数嗅探可以提供帮助 - 但它必须具有典型​​的参数值才能很好地创建计划,如果没有,则不会真正有帮助,或者会根据非典型参数值创建一个糟糕的计划。因此,如果变量的默认值为 null 或在第一次运行和编译计划时不是典型值,则会创建一个错误的计划。

如果其他人编写了这个存储过程 - 他们可能出于某种原因故意“禁用”局部变量的参数嗅探。业务规则可能需要这些可变结构。

目标是在创建计划之前获取有关 SQL 变量值的最佳/最多信息,通常参数嗅探会执行此操作。但有些事情可能会使其对性能产生负面影响,这可能就是它被“禁用”的原因。看起来该计划仍然是使用非典型参数值创建的,或者仍然没有足够的信息 - 使用或不使用参数嗅探。

尝试使用 sp_executesql 调用存储过程内的查询来执行受影响的查询,强制它使用实际变量为该区域生成计划,并查看是否更好。如果您必须拥有这种不规则的参数值,这可能是您的解决方案 - 创建运行受影响部分的存储过程,并稍后在变量收到典型值后从存储过程中调用它们。

如果没有看到实际代码的更好表示,就很难看出问题所在。希望这些信息会有所帮助 -

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

参数的性能不如硬编码值 的相关文章

  • 如何在 PostgreSQL 中使用具有多个值的 SQL LIKE 条件?

    有没有更短的方法来查找多个匹配项 SELECT from table WHERE column LIKE AAA OR column LIKE BBB OR column LIKE CCC 这个问题适用于 PostgreSQL 9 1 但如
  • 如何在存储过程中实现 sql 搜索功能 (Sql Server 2008)

    我需要编写一个存储过程 该过程将使用 sql server 2008 根据可选参数搜索表 将会有两种模式 基本搜索模式 我们只传递一些文本 高级搜索模式 使用可选参数而不使用 SearchText 为了进行测试 我使用 AdventureW
  • 是否有适用于所有数据库的标准sql

    如下所示 不同数据库的语法有所不同 是否存在适用于所有数据库的标准方法 有没有什么工具可以将任意sql转换为任意sql SQL Server 2005 CREATE TABLE Table01 Field01 int primary key
  • 使用 where 进行 select 语句时,HSQLDB 用户缺乏权限或未找到对象错误

    我的数据库使用 SQuirrel SQL 客户端版本 3 5 3 和 HSQLDB 我已经能够为其指定相应的驱动程序 内存中 并创建一个别名 我创建了一个表 CREATE TABLE ENTRY NAME VARCHAR 100 NOT N
  • 在 SQL 数据库中存储“列表”的最正确方法是什么?

    因此 我读了很多关于如何将多个值存储到一个列中是一个坏主意 并且违反了数据标准化的第一条规则 令人惊讶的是 这不是 不要谈论数据标准化 所以我需要一些帮助 目前我正在为我工 作的地方设计一个 ASP NET 网页 我想根据此人所属的 Act
  • PHP 通过 SSL 连接到 MS SQL

    我想要实现的目标非常简单 我想通过安全连接从 PHP 脚本连接到外部 MS SQL 数据库 然而 这已被证明是有问题的 到目前为止 经过三个小时的研究 我不知所措 客户端的平台是Ubuntu 这意味着我无法使用SQLSRV 安全连接已经在不
  • 使用 ADODB 连接从关闭的工作簿中检索数据。某些数据被跳过?

    我目前正在编写一些代码 可以通过 ADODB 连接访问单独的工作簿 由于速度的原因 我选择了这种方法而不是其他方法 下面是我的代码 Sub GetWorksheetData strSourceFile As String strSQL As
  • 实体框架 - SQL Server 2005 - IIS 服务器日期时间问题

    我正在使用 MVC3 和实体框架 在我的应用程序中 我需要通过 EF 调用 SQL Server 2005 中的存储过程来根据以下内容搜索一些数据datetime传递的参数 在当地环境中一切似乎都运行良好 但是将其托管到 IIS 后 我在尝
  • 自加入表

    我有一张像这样的桌子 Employee name salary a 10000 b 20000 c 5000 d 40000 我想获取所有工资高于A工资的员工 我不想使用任何嵌套或子查询 在采访中被问及并暗示是使用自连接 我真的不知道如何实
  • 月份增量查询

    我想通过添加 1 个月来更新数据库中的月份 但我不知道如何在以下存储过程查询中添加月份 我不擅长 sql 请检查它 ALTER PROCEDURE dbo ChangePassword password varchar 20 epasswo
  • 在 SQL 2005+ 中,CLR 存储过程是否优于 TSQL 存储过程?

    我目前的观点是否定的 更喜欢 Transact SQL 存储过程 因为它们是重量更轻且 可能 性能更高的选项 而 CLR 过程允许开发人员进行各种恶作剧 然而最近我需要调试一些写得非常糟糕的 TSQL 存储过程 像往常一样 我发现许多问题是
  • 计算运行总计时出错(之前期间的累计)

    我有一张桌子 我们称之为My Table有一个Created日期时间列 在 SQL Server 中 我试图提取一个报告 该报告显示历史上有多少行My Table按月在特定时间 现在我知道我可以显示有多少added每个月 SELECT YE
  • 临时表是线程安全的吗?

    我正在使用 SQL Server 2000 它的许多存储过程广泛使用临时表 数据库的流量很大 我担心创建和删除临时表的线程安全性 假设我有一个存储过程 它创建了一些临时表 它甚至可以将临时表连接到其他临时表等 并且还可以说两个用户同时执行存
  • 为什么我的 CASE 语句要求 THEN 部分的数据类型为 INT?

    我正在尝试运行一个查询 其中以下 CASE 语句是其中一行 我正在使用报表生成器 3 0 但是 我收到一条错误消息 将 varchar 值 Case 1 转换为 int 数据类型时转换失败 Microsoft SQL Server 错误 2
  • 使用间隔阈值对不同的连续时间戳记录进行分组

    我有一系列间歇性间隔的带有时间戳的 GPS 坐标 我正在使用 PostGIS 将它们渲染到地图画布上 为了渲染它们 需要使用 PostGIS 中的 ST MakeLine 聚合函数将点聚合成线 从而在地图上留下 GPS 数据丢失的间隙 数据
  • 如何使用 LAMBDA 表达式在 LINQ 中执行 IN 或 CONTAINS?

    我有以下 Transact Sql 我正在尝试将其转换为 LINQ 并且很挣扎 SELECT FROM Project WHERE Project ProjectId IN SELECT ProjectId FROM ProjectMemb
  • SQL Server 上的语法错误

    这可能是一个愚蠢的语法错误 但我只是继续阅读我的程序 但我无法弄清楚我的错误在哪里 消息 156 第 15 级 状态 1 第 41 行关键字附近的语法不正确 为了 这是我的代码 alter procedure LockReservation
  • Visual Studio 2010 中的数据库设计器

    我需要创建一个全新的 Sql Server 2008 数据库 并希望使用 Visual Studio 2010 Ultimate 中的数据库项目 我已经创建了该项目并在下面添加了一个表格dbo架构 桌子 sql仅以纯文本形式显示 但带有颜色
  • 在 SQL Server 中,如果主键是 GUID,如何按插入顺序对表行进行排序?

    我开始在主键中使用 GUID 而不是自动增量整数 然而 在开发过程中 我习惯于查询 从 SQL Management Studio 或 Visual Studio 数据库 以查看我的应用程序刚刚插入的记录 并且我对无法按主键 desc 顺序
  • VB6+SQL-Server:如何使用 ADODB.Command 执行带有命名参数的查询?

    我一直在尝试使用 ADODB Command 执行参数化查询 我知道我可以使用 对于参数 但我的查询相当大 我真的不想跟踪参数的确切顺序 我尝试了类似以下的操作 objCmd CommandType adCmdText objCmd Com

随机推荐

  • 从 Apache Kafka 中的主题删除消息

    所以我是 Apache Kafka 的新手 我正在尝试创建一个简单的应用程序 以便我可以更好地理解 API 我知道这个问题在这里被问了很多 但是如何清除存储在主题上的消息 记录 我看到的大多数答案都说要更改消息保留时间或删除并重新创建主题
  • Yegge 的原型模式示例如何处理实例变量?

    我喜欢史蒂夫 耶吉的原型模式示例 http steve yegge blogspot com 2008 10 universal design pattern html并决定快速制作一个概念验证示例 不过 我并没有真正考虑清楚 虽然它非常适
  • asp.net mvc - 如何在 javascript 中循环访问模型数据

    我试图用 javascript 将数据添加到列表框 但是字符串构建语法让我难住了 var yourobject 导致错误 字符文字中的字符太多 全部代码 var mlb cm createListBox mylistbox title My
  • Typescript 参数 - 对象的通用数组和对象键的数组(部分)

    我想要一个接受对象数组和一些对象键数组的方法 该方法将返回对象值数组的数组 但仅返回选定键的数组 data firstName Jane lastName Doe firstName John lastName Doe fields fir
  • C 风格强制转换与内在强制转换

    假设我已经定义了 m256d x我想提取低 128 位 我会做 m128d xlow mm256 castpd256 pd128 x 然而 我最近看到有人这样做 m128d xlow m128d x 是否有用于演员的首选方法 为什么要用第一
  • iOS 11.x 系统颜色

    我读过很多关于如何自定义视图颜色的文章 但没有任何关于检索标准控件 如 iOS 11 x 或以前版本中的导航栏 状态栏和选项卡栏 的系统颜色的文章 UIColor 类有 3 种系统颜色 但它们几乎没有用 例如 调用 UINavigation
  • PowerShell:如何在名称为“*”(星号/星号)的文件/文件夹上创建选择器?

    我需要从 PS 修改注册表 此注册表项与特定文件 所有扩展的文件夹 的上下文菜单相关 HKEY CURRENT USER Software Classes 目前我想将项目添加到此路径 HKCU Software classes shell
  • 解析XML文件以获取所有命名空间信息

    我希望能够从给定的 XML 文件中获取所有名称空间信息 例如 如果输入 XML 文件类似于
  • onKeyDown 和 onKeyLongPress

    我希望我的应用程序对音量按钮的正常按键事件和长按按键事件做出不同的反应 我已经看过了this https stackoverflow com questions 7493531 trying to catch the volume onke
  • Python,socket.error:[Errno 10049]

    在开发一个简单的聊天客户端的基础上 遇到以下错误 socket error Errno 10049 The requested address is not valid in its context 代码是 from socket impo
  • 支持的 Android 设备:0 台设备

    我们是 TourisMap 的开发商 我们不明白为什么在 Google Play 开发者控制台上上传 apk 后 我们支持 0 台设备 我们个人的想法是 Manifest 和 build gradle 都可以 我们可以生成 apk 然后我们
  • INSERT INTO ... SELECT ... 是否始终按序号位置匹配字段?

    我的测试似乎证实了这一点 INSERT INTO a x y SELECT y x FROM b maps b y to a x 即字段仅按顺序位置匹配 而不按名称匹配 情况总是如此吗 即 我可以依赖这种行为吗 很遗憾 文档 http ms
  • 将 wgs 84 转换为纬度/经度

    你好 我在弄清楚如何在坐标类型之间进行转换时遇到了一些麻烦 我有一个坐标集列表 其描述如下 坐标始终采用 WGS84 系统 所有坐标 a 均表示为整数 值 x 和 y 其中坐标值乘以 1 000 000 一个例子 559262 631951
  • 是否有适合 Java 1.4 和 SE (Swing) 应用程序的优秀 DI 框架?

    我正在寻找一个适用于在 JDK 1 4 下运行的 Java SE Swing 应用程序的依赖注入框架 有没有我可以使用的推荐 DI 框架 Guice 和其他基于注释的框架已经退出 我不想搞乱像 Retroweaver 这样的东西 另外 Sp
  • Webworker-threads:在工作线程中使用“require”可以吗?

    使用 Sails js 我正在测试 webworker threads https www npmjs com package webworker threads https www npmjs com package webworker
  • 什么是稀疏体素八叉树?

    我读了很多关于稀疏体素八叉树在未来图形引擎中的潜在用途的文章 但是我一直无法找到有关它们的技术信息 我理解体素是什么 但是我不知道稀疏体素八叉树是什么 或者它们如何比现在使用的多边形技术更有效 有人可以解释或指出我对此的解释吗 这是一个关于
  • 将 pandas DataFrame 写入 unicode 中的 JSON

    我正在尝试将包含 unicode 的 pandas DataFrame 写入 json 但是内置的 to json函数对字符进行转义 我该如何解决 Example import pandas as pd df pd DataFrame a
  • 哪些 2to3 修复程序输出有效的 Python 2 代码?

    2to3 是一个 Python 程序 它读取 Python 2 x 源代码并应用一系列修复程序将其转换为有效的 Python 3 x 代码 考虑一下列出的四十个修复者https docs python org 3 library 2to3
  • jquery中(“*”)有什么用

    我正在阅读 jQuery 我不知道为什么使用 请解释一下这有帮助 是jquery中的一个选择器 它可以无条件地选择所有内容 包括html head和body 这是一个解释其用法的示例 document ready function butt
  • 参数的性能不如硬编码值

    我有一个执行得很糟糕的存储过程 当我声明一个变量时 设置它的值 然后在 where 子句中使用它 该语句需要一个多小时才能运行 当我对 where 子句中的变量进行硬编码时 它的运行时间不到一秒 我开始通过执行计划来查找问题所在 看起来当我