SQL Server查询优化 - 这里的最佳索引是什么?

时间:2013-11-27 11:33:19

标签: sql sql-server indexing

我有一个电子邮件发送表,需要保存超过400万行。一个特定的报告也需要参考这个表来产生一些统计数据,并且它比我想要的运行时间更长(目前大约30秒)。

我已经检查了估计的执行计划,该计划显示94%的成本是由单个谓词引起的(如果我正确地解释了这一点)。

请注意,以下示例显示了小片段以保持简洁。其他索引针对其他查询。

enter image description here

谓词:

[EmsDb].[dbo].[MailDispatchPending].[MailCampaignId]=[@MailCampaignId] OR [@MailCampaignId] IS NULL

我相信这是指向以下SQL:

WHERE @MailCampaignId IS NULL OR MailCampaignId = @MailCampaignId -- Restrict to mail campaign where parameter passed

我试图通过测试以下索引来提高性能。既不会影响执行计划输出,也不会提高查询速度。

/****** Object:  Index [IX_MailCampaignId]    Script Date: 11/27/2013 11:21:00 ******/
CREATE NONCLUSTERED INDEX [IX_MailCampaignId] ON [dbo].[MailDispatchPending] 
(
    [MailCampaignId] ASC

)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

/****** Object:  Index [IX_MailCampaignId]    Script Date: 11/27/2013 11:21:00 ******/
CREATE NONCLUSTERED INDEX [IX_MailCampaignId] ON [dbo].[MailDispatchPending] 
(
    [Id] ASC,
    [MailCampaignId] ASC

)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

有人可以建议更好的索引类型或不同的策略来帮助我提高绩效吗?

3 个答案:

答案 0 :(得分:3)

不要使用这种方法:

WHERE @MailCampaignId IS NULL OR MailCampaignId = @MailCampaignId

改为使用:

IF @MailCampaignId IS NULL
    BEGIN
        SELECT  ..
        FROM    ...
    END
ELSE
    BEGIN
        SELECT  ..
        FROM    ...
        WHERE   MailCampaignId = @MailCampaignId
    END 

它可能感觉更多工作,但SQL-Server使用缓存的执行计划,除非您强制重新编译,否则它将使用相同的执行计划,无论参数是否为null。如果使用上述方法,则可以保证使用正确的计划,具体取决于参数是否为空

答案 1 :(得分:2)

IS NULL OR部分会影响你的表现,因为如果输入为NULL,你就会要求每一行都是扫描。

如果可能的话,我会删除那个部分,看看是否有帮助,如果不可能,那么我会重新考虑我何时需要所有这些并考虑替代方法,例如多个查询而不是一个甚至是存储变化。

答案 2 :(得分:0)

这可能是@GarethD提出的替代解决方案吗?

WHERE MailCampaignId = COALESCE(@MailCampaignId,MailCampaignId)