【问题标题】:Query that uses Clustered Index Scan instead of seek使用聚集索引扫描而不是查找的查询
【发布时间】:2025-12-22 17:05:07
【问题描述】:

我有以下查询,它返回

  • Sql Server 2008 R2
  • 表 PMDME 大约 140,000 行(这是占用 41% 资源的行)
  • 服务器硬件:16 核 2.7gz 处理器,48gb 内存
声明@开始日期,@结束日期 SET @start = '2013-01-01' SET @end = CAST(GETDATE() 作为日期) 选择 b.总计, c.摄入量, d.船舶, a.CODE_, RTRIM(a.NAME_) 作为名称, f. 雇员作为销售员, g.referral_type_id, h.referral_type, e.slscode, 一座城市, 一个状态_, 一个.zip 来自 PAWARE.ADS.RFDME 左外连接 ( SELECT SUM(b.quantity) total, a.ref_id from event.dbo.sample a 在 a.id = b.sample_id 上加入 event.dbo.sample_parts b 在 b.part_id = c.CODE_ 上加入 PAWARE.ADS.PTDME c 其中 c.MEDICAREID = 'E0607' AND a.order_date 在 @start 和 @end 之间 按 a.ref_id 分组 )b 上 a.CODE_ = b.ref_id 左外连接 ( 选择 COUNT(a.CODE_) 作为摄入量,rfcode 来自 PAWARE.ADS.PMDME @start 和 @end 之间的 a.REGDATETIME GROUP BY a.RFCODE ) c on a.CODE_ = c.rfcode 左外连接 ( 选择 COUNT(a.CODE) 作为船舶,b.rfcode 从 ( 选择 A.帐户代码, MIN(CAST(A.BILLDATETIME AS DATE)) AS SHIPDATE 来自 PACWARE.ADS.ARODME A 在 A.PTCODE=B.CODE_ 上左外连接 PACWARE.ADS.PTDME B 左外连接 event.dbo.newdate() D ON A.ACCOUNT=D.ACCOUNT 左外连接 event.dbo.newdate_extras() D2 ON A.ACCOUNT=D2.ACCOUNT A.BILLDATETIME>=@start AND A.BILLDATETIME=@start AND D.NEWDATE=@start AND D2.NEWDATE'ID' 通过...分组 A.帐户, B.医疗保险, A.类别 ) 一个 在 a.CODE = b.CODE_ 上加入 PAWARE.ADS.PMDME b 按 b.RFCODE 分组 ) d on a.CODE_ = d.rfcode 左外连接 event.dbo.employee_slscode e on a.SLSCODE = e.slscode 在 e.employee_id = f.id 上加入 event.dbo.employee f 在 a.CODE_ = g.CODE_ 上加入 event.dbo.referral_data g 在 g.referral_type_id = h.id 上加入 event.dbo.referral_type h 总计 > 0

【问题讨论】:

  • 上次在您的数据库上运行表和索引统计信息是什么时候?
  • 我不明白你的意思,我在一分钟前运行了这个查询的执行计划(对不起,不是数据库管理员,这里有点超出我的深度)
  • 作为附加说明,此查询作为带有参数@start and @end 的表值函数运行,如果这有什么不同的话
  • PACWARE.ADS.PMDME.CODE_ 是哪种列?是PACWARE.ADS.PMDME表的PK吗?乍一看,我会开始为PACWARE.ADS.PMDME.REGDATETIMEPACWARE.ADS.PMDME.CODE_ 创建和索引。但首先,我会在 'Database Engine Tunning Advisor' 中运行该查询并查看 SQL Server 为您提供哪些索引,大多数时候(但不是每次)都会足够聪明地知道哪个索引是你需要的。
  • PACWARE.ADS.PMDME.CODE_ 是一个 CHAR(4) 并设置为 PK 集群

标签: performance sql-server-2008 indexing


【解决方案1】:

我会先尝试为PACWARE.ADS.PMDME 表上的列REGDATETIME 创建索引。

GO
CREATE NONCLUSTERED INDEX [IX_PMDME_REGDATETIME] ON PACWARE.ADS.PMDME
(
    [REGDATETIME] ASC
)
GO

测试它是如何工作的。如果selectivity of the column 足够好,我还将测试向RFCODE 列(同一张表)添加另一个索引。

【讨论】: