使用 SQL Server 索引来提高性能

Posted

技术标签:

【中文标题】使用 SQL Server 索引来提高性能【英文标题】:Using SQL Server indexes to increase performance 【发布时间】:2020-01-31 19:17:17 【问题描述】:

我们使用的是 SQL Server 和 SSMS 18.4。

我们有一个包含这些列的TripAsset 表:

TripAssetID
TripID
Attachment1
Attachment2
Attachment3

我们有一个网格视图,其中列出了行程和行程文件中的数据。网格中的每一行都必须表明行程有Attachment1、Attachment2、Attachment3等。

执行此操作的 SQL 是加入 TripAsset 表并检索整个附件(可能非常大),以表明附件存在。这显然非常缓慢。

程序员建议创建一个单独的文件,其中包括TripIDhasAttachment1hasAttachment2hasAttachment3 等。然后某些进程会保持此表与TripAsset 表同步。

我认为必须有更好的方法,所以我像这样创建了索引tripHasAttachment1

CREATE INDEX tripHasAttachment1
ON [dbo].[TripAsset] (TripID)
WHERE [TripAsset].[Attachment1] IS NOT NULL

现在我可以运行如下查询,其中tripID 是我想查看是否有附件的行程。

SELECT TripID 
FROM TripAsset WITH(INDEX(tripHasAttachment1)) 
WHERE TripID = [tripID]

这似乎运行得很快。

这是解决此问题的最佳方法吗?我需要 with 子句吗?

如果有任何建议,我将不胜感激。

【问题讨论】:

实际上,这里显示的架构使用了“重复组”。它有三个字段来描述附件...不多也不少...实际上这表示 一对多的关系 确实应该由两个表表示:TripAsset 和 @ 987654334@. 我以前从未见过这样使用过的索引。难道你不能在 TripID 上有一个普通的索引,然后把“where is not null”放到主查询中吗? @Mike 但实际上,不这样做可能有充分的理由。 如果可能的话,我不想更改 TripAsset 表中的架构。现在可能不是最好的设计,但它已嵌入到我们的系统中。我喜欢 Stu 在下面的回答,我认为您的意思是将“where is not null”放入主句中。 “程序员建议创建一个单独的文件” - 因无能而被解雇。解决了一个问题。不需要单独的文件。 【参考方案1】:

您不需要检索附件来检查它是否存在:

Select
  TripAssetID,
  TripID,
  HasAttachment1 = Cast((Case When Attachment1 Is Null Then 0 Else 1 End) As Bit),
  HasAttachment2 = Cast((Case When Attachment2 Is Null Then 0 Else 1 End) As Bit),
  HasAttachment3 = Cast((Case When Attachment3 Is Null Then 0 Else 1 End) As Bit)
From
  TripAsset

【讨论】:

斯图,我喜欢这个答案。我们有几个程序员在做这个项目,程序员来来去去。您是否建议将其放入存储过程中并指导人们使用 SP 来检查附件是否存在,而不是点击文件本身? 如果您的开发人员不一定精通 SQL,我建议创建一个 VIEW 并让每个人都切换到使用它(直到并包括通过撤销直接查询表的权限来强制执行)。

以上是关于使用 SQL Server 索引来提高性能的主要内容,如果未能解决你的问题,请参考以下文章

DBCC DBREINDEX重建索引提高SQL Server性能

DBCC DBREINDEX重建索引提高SQL Server性能

应该针对不同的排序和过滤条件创建哪些MongoDB索引来提高性能?

mysql有哪些饮鸩止渴提高性能的方法

C#笔记

浅谈 SQL Server 查询优化与事务处理