sql - 使用变量时的查询性能

标签 sql sql-server

我有一个包含大约 2 亿行的表。该表包含许多列,但目前只有主键和一个基于日期时间列的非聚集索引。

第一个查询将在不到一秒内返回零行。

SELECT *
FROM GenericTable
WHERE GenericDate > '01-01-1753' AND GenericDate <= '01-29-1753'

此查询返回零行的时间过长,大约两分钟。

DECLARE @startDate DATETIME, @endDate DATETIME

SET @startDate = '01-01-1753'
SET @endDate = '01-29-1753'

SELECT *
FROM GenericTable
WHERE GenericDate > @startDate AND GenericDate <= @endDate

使用包含数据的日期范围,性能会好一点吗?第一个查询将在不到一秒的时间内返回 1000 行,第二个查询仍然需要 30 秒或更长时间才能返回相同的数据。

编辑:我还让它显示了执行计划,第二个查询没有使用索引?

第一个查询:

Select <- Nested Loops (Inner Join) - 0% <- Index Seek (NonClustered) - 0%
                                         <- Key Lookup (Clustered) - 100%

第二个查询:

Select <- Parallelism (Gather Streams) - 10% <- Clustered Index Scan (Clustered) - 90%

最佳答案

这是一个众所周知的执行计划缓存和参数问题 嗅探。

引自this article

A while back I wrote about parameter sniffing, the situation where SQL compiles and caches an execution plan that is appropriate for a certain value of a parameter, but is non optimal for other values. There’s another side to parameter sniffing though – when the optimiser can’t sniff at all.

When a batch is submitted to the optimiser, the value of any parameters (from stored procedure, auto parametrisation or sp_executesql) are known to the optimiser. So are the value of any constants used in the SQL statement. The value of local variables, however, are not.

When the value of a variable used in the where clause is not known, the optimiser has no idea what value to use to estimate the number of affected rows. Hence, it has no idea how many rows from the table will satisfy the condition.

关于sql - 使用变量时的查询性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38361164/

相关文章:

MySQL 使用单行作为 Where In

mysql - 我的sql查询一直在获取,是代码还是其他什么?

sql - sql server 比较同一个数据库中的两个表的数据

c# - 如何优化 LINQ 查询?

java - 如何将不同列的值分组到一行中?

sql - 查询帮助查找丢失的号码

sql - 什么是索引以及如何使用它们来优化数据库中的查询?

php - 将 WHERE 和 GROUP BY 合并到日期时间总和 MySQL 查询中

sql - 如何进行数据透视并计算列平均值

sql-server - 使用 SQL 中的外部表/Polybase 从外部源(Azure 存储 Blob)中选择数据。表已创建但未返回数据