【问题标题】:Getting a query to index seek (rather than scan)获取查询以查找索引(而不是扫描)
【发布时间】:2009-07-31 08:19:12
【问题描述】:

运行以下查询 (SQL Server 2000),执行计划显示它使用了索引查找,而 Profiler 显示它正在执行 71 次读取,持续时间为 0。

select top 1 id from table where name = '0010000546163' order by id desc

与以下情况相比,使用具有 8500 次读取和大约一秒的持续时间的索引扫描。

declare @p varchar(20)
select @p = '0010000546163'
select top 1 id from table where name = @p order by id desc

为什么执行计划不同?有没有办法改变第二种寻找的方法?

谢谢

编辑

表格看起来像

CREATE TABLE [table] (
    [Id] [int] IDENTITY (1, 1) NOT NULL ,
    [Name] [varchar] (13) COLLATE Latin1_General_CI_AS NOT NULL)

Id 是主聚集键 Name 上有一个非唯一索引,id/name 上有一个唯一复合索引 还有其他列 - 为简洁起见将它们省略

【问题讨论】:

  • 请问什么数据类型/模式?

标签: tsql sql-server-2000


【解决方案1】:

现在您已经添加了架构,请试试这个。 SQL Server 将长度差异视为不同的数据类型,并将转换varchar(13) 列以匹配varchar(20) 变量

declare @p varchar(13)

如果不是,那么排序规则强制呢?数据库或服务器与列不同吗?

declare @p varchar(13) COLLATE Latin1_General_CI_AS NOT NULL

如果没有,请在前面添加并发布结果

SET SHOWPLAN_TEXT ON
GO

【讨论】:

  • 非常感谢 - 更改为 varchar(13) 成功了。我不知道变量的大小会改变执行计划。你能解释一下为什么吗?再次感谢。
  • @PaulB: varchar(13) 将被更改为 varchar(20) 索引将被忽略并且扫描发生 = 较慢...很晚回复抱歉
【解决方案2】:

如果名称列是 NVARCHAR 那么你需要你的参数也是相同的类型。然后它应该通过索引查找来获取它。

declare @p nvarchar(20)
select @p = N'0010000546163'
select top 1 id from table where name = @p order by id desc

【讨论】:

  • 它将@p 转换为 nvarchar 因为它具有更高的优先级,而不是列
猜你喜欢
  • 1970-01-01
  • 2020-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-05
  • 1970-01-01
相关资源
最近更新 更多