使用参数时“Between”运算符生成错误的查询计划

2024-03-01

我有一个简单的日期表(Date,DateID),其中包含 1900 年 1 月 1 日到 2100 年 12 月 31 日之间的日期列表。

当使用从表中选择时between运算符和硬编码参数值,我得到了一个正确的查询计划,其中有 3 个估计行与 2 个实际行相比:

select v.Date from Dates v
where v.Date between '20130128' and '20130129';

然而,当用参数替换硬编码值时,查询计划会变成一个非常糟糕的计划,估计有超过 6000 行,而实际只有 2 行:

select v.Date from Dates v
where v.Date between @startdate and @enddate;

查询计划本身是相同的,只是估计行数的差异导致参数化查询的运行速度比硬编码查询慢大约 4 倍。对于参数化版本运行速度如此慢的原因,我是否遗漏了什么,以及我可以为 SQL Server 提供哪些索引/提示来帮助它使用正确的查询计划?

一些附加信息:

  • 使用简单相等时不会出现问题=标准,似乎特定于between操作员。
  • 如果我添加option(recompile)在参数化查询结束时,我得到了一个完美的查询计划,与硬编码查询相同。
  • 日期表只有两列:Date 和 DateID,主键 DateID 列上有一个聚集索引,Date 列上有一个唯一的非聚集索引。所有这些都已更新统计数据。
  • 查询计划对硬编码查询执行自动参数化,用@1和@2替换硬编码值,并将查询显示为大写。它似乎没有对参数化查询执行任何转换。
  • 使用 SQL Server 2008 R2。

我知道的足够意识到suspect这是某种参数嗅探问题。为什么不添加option(recompile)到查询?这被用作一个更大的复杂查询的一部分,我知道好的做法是让 SQL Server 做它的事情,并在可能的情况下重用缓存中的查询计划。

编辑和更新:感谢迄今为止的深思熟虑的回复。为了进一步细化问题,查询计划对上述两个查询都使用了一个完美的索引,但是为什么它没有认识到参数化查询的日期范围只有两天,为什么它认为范围是 6000行宽?尤其是当查看查询计划时,SQL Server 无论如何都会为硬编码查询执行自动参数化?在底层查询计划中,两个计划看起来相同,因为它们都是参数化的!


查询计划基于首次运行查询时的参数值。这就是所谓的参数嗅探 http://www.sommarskog.se/query-plan-mysteries.html。当你添加option (recompile),每次执行都会生成一个新计划。

查询计划根据 SQL 查询的哈希进行缓存。因此,两个版本的查询都有不同的缓存槽。

Adding option (recompile)是一个很好的解决方案。您还可以使用:

option (optimize for (@startdate = '20130128', @enddate = '20130129'));

生成查询计划,就好像这些值已传入一样。

为了进行测试,您可以使用以下命令从缓存中删除所有计划:

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

使用参数时“Between”运算符生成错误的查询计划 的相关文章

  • 可以使用表通配符创建 sql 查询吗?

    这可能是一个简单的问题 但我无法在网上找到解决方案 任何帮助将不胜感激 我正在尝试在 PHP 中创建一个 SQL 查询 并希望以某种方式将通配符应用于 TABLE 过滤器 可能是这样的 select from table 但是 到目前为止我
  • 在c#中创建sql连接

    我是这个网站的新手 也是编程的新手 我目前正在通过销售点创建库存系统 它使用模态和非模态形式 我的问题是 我正在研究change password对话框必须连接到数据库才能覆盖密码字段 我使用的数据库是Microsoft SQL Serve
  • Postgresql 一张表的多个计数

    我想从表中的两列中获得这些列中值的统一计数 例如 两列是 表 报告 type place one home two school three work four cafe five friends six mall one work one
  • Oracle:如何获取刚刚插入的行的序列号?

    如何获取刚刚插入的行的序列号 插入 返回 declare s2 number begin insert into seqtest2 x values aaa returning seq into s2 dbms output put lin
  • 通过 osql.exe 运行脚本时出现问题

    我尝试以这种格式运行我的软件的更新脚本 osql exe i path to script U 用户 P 密码 S sqlserver 位置 d 数据库名称 n b 大多数脚本的格式相同 并且都以 GO 结尾 其中很多都运行得很好 但随机脚
  • 什么时候应该使用 C++ 而不是 SQL?

    我是一名 C 程序员 偶尔使用 MySQL 来处理数据库 但我的 SQL 知识相当有限 但我肯定愿意改变这一点 目前 我正在尝试仅使用 SQL 查询对数据库中的数据进行分析 但我准备放弃了 转而将数据导入到C 中 用C 代码进行分析 我和同
  • 如何通过子 POJO 的属性过滤复合 ManyToMany POJO?

    我有两个像这样的房间实体 Entity public class Teacher implements Serializable PrimaryKey autoGenerate true public int id ColumnInfo n
  • JDBC插入实数数组

    我试图将一个真实的数组插入到 postgresql 数组中 该表的定义是 String sqlTable CREATE TABLE IF NOT EXISTS ccmBlock sampleId INTEGER block REAL 插入内
  • 在存储过程中验证用户的最简单方法?

    我需要一个存储过程 可以通过发送以下内容来检查登录尝试时他们是否是有效用户login and password查看它们在数据库中是否匹配 有没有一种简单的方法可以做到这一点 如果没有更多信息 我目前能提供的最好信息是 CREATE STOR
  • 数据库字段中的逗号分隔值

    我有一个产品表 该表中的每一行对应一个产品 并由唯一的 ID 标识 现在 每个产品都可以有多个与该产品关联的 代码 例如 Id Code 0001 IN ON ME OH 0002 ON VI AC ZO 0003 QA PS OO ME
  • 在 SQL Server 上执行分页的最佳方式是什么?

    我有一个数据库超过200万记录 我需要执行分页以在我的 Web 应用程序上显示 该应用程序每页必须有 10 条记录DataGrid 我已经尝试使用ROW NUMBER 但是这种方式会选择所有 200 万条记录 然后只得到 10 条记录 我也
  • 如何在MYSQL中将整个字符串小写并保持第一个大写[重复]

    这个问题在这里已经有答案了 我的表栏目 我预期的输出会在列中发生变化 Smith Allen Doyle Dennis Baker Waker 这是我尝试过的 但不起作用 UPDATE TABLE employee SET last nam
  • 如何识别拼写不同的相似单词

    我想从数据库中过滤掉重复的客户名称 一位客户可能有多个同名但拼写差异不大的系统条目 这是一个示例 名为 Brook 的客户可能有 3 个系统条目 有了这个变化 布鲁克 贝尔塔 布鲁克 贝尔塔 比鲁克 贝尔塔 假设我们将此名称放入一个数据库列
  • 读取 BCP 格式文件时发生 I/O 错误

    今天 我创建了一个新的临时表和一个 BCP fmt 文件 我创建了一些测试数据并尝试从命令行运行 BCP 实用程序 我从之前的工作中获得了大约 20 个不同格式的文件和暂存表 这是我第一次遇到此错误 我该如何修复这个错误 请注意 我在下面添
  • 是否有适用于 SQL Server Express 的 SQL Server Profiler? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 是否有适用于 SQL Server Express 的 SQL Server Profiler 也许是开源的 或者也许只是一个可以帮助我查
  • SELECT max(x) 返回 null;我怎样才能让它返回0?

    运行以下命令时如何返回 0 而不是 null SELECT MAX X AS MaxX FROM tbl WHERE XID 1 假设没有XID 1的行 or SELECT coalesce MAX X 0 AS MaxX FROM tbl
  • 同时从2个表中删除?

    我正在使用 asp net 和 sql 服务器 我有 2 个表 类别和产品 在产品表中 我的categoryId 为FK 我想要做的是 当我从类别表中删除类别时 我希望该类别中的所有产品都将在产品表中删除 如何才能做到这一点 我更喜欢使用存
  • 关键字“table”附近的语法不正确,无法提取结果集

    我使用 SQL Server 创建了一个项目 其中包含以下文件 UserDAO java public class UserDAO private static SessionFactory sessionFactory static se
  • 我是否需要在外键上指定 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 创建了一个安装向导来安装应用程序 这些是我在目标计算机中安装应用程序所执行的步骤 安装

随机推荐

  • Python 无法从包中导入模块

    我有一个具有以下布局的 Flask Restful 项目 为方便起见更改了文件名 myproject init py app py common init py util py foo init py main py utilities p
  • 使用 HtmlAgilityPack 对特定子节点进行计数

    我在 HtmlAgilityPack 中使用的 XPath 选择遇到了很多麻烦 我想选择全部li嵌套在另一个元素中的元素 如果存在 li女巫有a标记为id menuItem2 这是 html 示例 div ul li a a li li a
  • 矩阵和算法“螺旋”

    我想问是否有一些算法准备好 允许我这样做 我有一个矩阵 m 列 x n 行 其中有 m x n 元素 我想给这个元素从中心开始并以螺旋形式旋转的位置 例如 对于 3x3 的矩阵 我有 9 个这样定义的元素 5 6 7 4 9 8 3 2 1
  • 如何从 CodeIgniter 内部访问标准 PHP 会话数据

    我正在开发一个 Codeigniter 项目 并使用 CI 会话 存储在数据库中 但我需要检查另一个应用程序 在同一个 cookie 域中 的另一个 SESSION 中的变量 但是当我尝试从 CI 控制器使用本机 PHP 会话来获取这一点信
  • Base X 字符串编码

    我正在寻找一个例程 将字符串 字节流 编码为任意基本 字母表 如base64编码 但我可以选择字母表 我见过一些例程对数字进行基本 X 编码 但不对字符串进行基本 X 编码 这是我的BaseX BaseN 编码算法的实现 https git
  • 使用模型工厂、一对一和一对多关系定义 Laravel 外键,无需创建不必要的模型

    最近 我一直在尝试通过 Model Factories 和 Faker 使用 Laravel 播种来为我的数据库播种 对于简单的模式 让它工作是轻而易举的 然而 我在处理复杂的数据库模式时遇到了几个问题 其中涉及外键和表关系 一对一 一对多
  • 安装 reflex-dom 可能会破坏 ghcjs

    我正在尝试安装reflex and reflex dom using cabal install我收到以下错误消息 cabal install reflex dom cabal The following packages are like
  • 确定查询是否在 vb.net 中返回“无行”

    我使用 MS SQL Server 作为数据库 使用 VB NET 作为后端 我想确定 sql 命令文本中的查询是否不返回任何行 我尝试有一个不返回任何行的查询 然后将其值赋给一个文本框 该文本框变为 0 整数 现在的问题是 当我在一个如果
  • 节能器启用和禁用后后台服务停止

    我有一个应用程序 在其中我在后台执行一些任务 因此 如果我的后台服务正在运行 该任务就会执行 问题 当我启用和禁用省电程序时 它会关闭所有内容并停止正在运行的每个后台服务 关闭省电程序后 直到我打开应用程序后 服务才开始启动 那么 对于低于
  • 何时使用 Apache 与 Apache+Tomcat?

    既然简单地使用 Apache 就足以运行许多 Web 应用程序 那么除了 Apache 之外 人们何时以及为何还使用 Tomcat 阿帕奇雄猫 http tomcat apache org是 Web 服务器和 Java servlet 容器
  • 如何改进这个平方根方法?

    我知道这听起来像是一项家庭作业 但事实并非如此 最近我对用于执行某些数学运算的算法感兴趣 例如正弦 平方根等 目前 我正在尝试编写巴比伦方法 http en wikipedia org wiki Babylonian method Baby
  • 如何从python中的pandas数据框中的列中提取关键字(字符串)

    我有一个数据框df它看起来像这样 id Type agent id created at 0 44525 Stunning 6 bedroom villa in New Delhi 184 2018 03 09 1 44859 Villa
  • 前向声明不适用于转换运算符

    考虑下一个代码 include
  • Android:以编程方式在 EditText 内居中文本

    有没有办法让输入的文本居中EditText场地 更具体地说 光标不应从框的左侧开始 而应从中心开始 并在填充输入时向外向左移动 你应该使用 textView setGravity Gravity CENTER HORIZONTAL
  • 通过 PEAR 安装 phpunit 后如何获得 phpunit.bat?

    我需要 phpunit bat 来配置我的 NetBeans IDE 我在用着wamp http www wampserver com 我只需使用以下说明通过 pear 安装 phpunit 在开始使用 PEAR 之前 请从以下位置下载最后
  • 如何找到我的 MySQL URL、主机、端口和用户名?

    我需要找到我的 MySQL 用户名 当我打开 MySQL 命令行客户端时 它只询问我的密码 我不记得我的用户名了 为了与 JDBC 连接 我需要 URL 主机和端口号 我在哪里可以找到所有这些 如果您已经登录命令行客户端 请尝试以下操作 m
  • 在 Geodjango + Postgres 中存储圆

    希望在 geodjango 字段中存储一个圆 以便我可以使用 geodjango 查询 contains 来查找圆中是否有一个点 类似于使用 PolygonField 可以完成的操作 目前将其存储为十进制半径和 GeoDjango 点字段
  • 如何使用 Google Calendar API v3/Google API 客户端库显示*所有*可用日历的列表?

    我一直在尝试使用 PHP 访问 Google Calendar API v3 最初 我想简单地列出我可以通过 API 调用访问的用户日历 为此 我下载了 Google API PHP 客户端库 并尝试使用以下代码 经过我的改编 来自http
  • IIS 7.5 上的 MVC5 路由错误 (404.0) 错误

    一个古老的故事是 在开发机器上一切正常 但在主机服务器上却不行 HTTP 错误 404 0 未找到 模块IIS 网络核心 通知地图请求处理器 处理程序静态文件 错误代码0x80070002 尝试通过添加在开发机器上产生相同的错误
  • 使用参数时“Between”运算符生成错误的查询计划

    我有一个简单的日期表 Date DateID 其中包含 1900 年 1 月 1 日到 2100 年 12 月 31 日之间的日期列表 当使用从表中选择时between运算符和硬编码参数值 我得到了一个正确的查询计划 其中有 3 个估计行与