这是我的查询:
With cte as (
Select
ROW_NUMBER() OVER (Order By d.OldInstrumentID ) peta_rn,
d.DocumentID
From Documents d
Inner Join Users u on d.UserID = u.UserID
Where 1=1
And (d.JurisdictionID = 1 Or DocumentStatusID = 5 Or DocumentStatusID = 9)
And d.DocumentStatusID <> 3 And d.DocumentStatusID <> 8
And d.DocumentStatusID <> 7
AND ((CreatedByJurisdictionID = 1 Or DocumentStatusID = 5 Or DocumentStatusID = 9 Or CreatedByAccountID IN (Select AccountID From AccountsJurisdictions Where JurisdictionID = 1)))
And d.DocumentStatusID = 9
)
Select
d.DocumentID,
d.IsReEfiled,
d.IGroupID,
d.ITypeID,
d.RecordingDateTime,
d.CreatedByAccountID,
d.JurisdictionID,
Case
When d.OldInstrumentID IS NULL
THEN d.LastStatusChangedDateTime
Else d.RecordingDateTime
End as LastStatusChangedDateTime,
dbo.FnCanChangeDocumentStatus(d.DocumentStatusID,d.DocumentID) as CanChangeStatus,
d.IDate,
d.InstrumentID,
d.DocumentStatusID,
d.DocumentDate,
Upper(dbo.GetFlatDocumentName(d.DocumentID)) as FlatDocumentName
From Documents d
Inner Join cte on cte.DocumentID = d.DocumentID
Where 1=1
And peta_rn>=80000
AND peta_rn<=80050
Order by peta_rn
DB 中几乎没有 100,000 条记录,但此查询执行大约需要 2 秒才能获取 50 条记录。完全不能接受!我什至在大多数使用连接的列上都有索引。
在 CTE 的基本子句中进行了单个连接,但这是必需的。我知道加入是杀手,但我需要 1 加入。如果这删除这段代码:
And (d.JurisdictionID = 1 Or DocumentStatusID = 5 Or DocumentStatusID = 9)
And d.DocumentStatusID <> 3
And d.DocumentStatusID <> 8
And d.DocumentStatusID <> 7
AND ((CreatedByJurisdictionID = 1 Or DocumentStatusID = 5 Or DocumentStatusID = 9 Or CreatedByAccountID IN (Select AccountID From AccountsJurisdictions Where JurisdictionID = 1)))
And d.DocumentStatusID = 9
它运行得非常快。在 SSMS 中显示 0 秒。有什么方法可以加快这个查询?我需要这些条件,因为它们甚至没有那么大。为什么条件会减慢查询速度?我已经在 CreatedByAccountID 和其他列上有索引。真的很烦!
编辑:
感谢您的回复。更多细节:
你们中的许多人建议删除多余的条件。抱歉,这段 SQL 是在代码中动态形成的,我将该版本粘贴到 SSMS 和此处。从 where 子句中删除这些条件无济于事:
Where 1=1
And (d.JurisdictionID = 1 Or d.DocumentStatusID = 5 Or d.DocumentStatusID = 9)
And d.DocumentStatusID <> 3
And d.DocumentStatusID <> 8
And d.DocumentStatusID <> 7
AND ((CreatedByJurisdictionID = 1 Or DocumentStatusID = 5 Or DocumentStatusID = 9 Or CreatedByAccountID IN (Select AccountID From AccountsJurisdictions Where JurisdictionID = 1)))
And d.DocumentStatusID = 9
事实上,只要我放入 where 子句,它就会变慢。所以,即使这个也很慢:
Where 1=1
And (d.JurisdictionID = 1 Or d.DocumentStatusID = 5 Or d.DocumentStatusID = 9)
更多细节。Row_Number() 中的 order by 子句是决定因素。OldInstrumentID
varchar(14) 类型很慢,需要 2 秒,而如果我按d.DocumentID
int 类型排序,即使我保留所有这些冗余条件,它也会在 0 秒内正常工作。
这是我的执行计划:
更新:
我在每一列上创建了这样的索引,它似乎运行得非常快。呜呜呜!!!
Create NonClustered Index IX_DocumentDate on Documents
(
DocumentDate
)
Include(
JurisdictionID,
JudgementTypeID,
IDate,
EfileDate,
UserID,
RecordingDateTime,
ApprovedBy,
ACEfileBankAccountID,
LastStatusChangedDateTime,
ACEfileCreditCardID,
EfiledByUserID,
ITypeID,
IGroupID,
InstrumentID,
OldInstrumentID,
[CreatedByJurisdictionID],
CreatedByAccountID,
[DocumentStatusID]
,[Remarks]
,[InternalNotes]
,[ParentDocumentID]
,[FilingNumber]
,[StampData]
,[Receipt]
,[ReceiptNo]
,[IsReEfiled]
,[ImportedFromInstrumentID]
)