我有一个旧视图需要4分钟才能运行,我被要求加快速度。 FROM看起来像这样:
FROM TableA
CROSS JOIN ViewA
INNER JOIN TableB on ViewA.Name = TableB.Name
AND TableA.Code = TableB.Code
AND TableA.Location = TableB.Location
WHERE (DATEDIFF(m, ViewA.SubmitDate, GETDATE()) = 1) -- Only pull last months rows
表A有大约99k行,ViewA有大约2000行,TableB大约有101K行。我认为问题出在INNER JOIN,因为我将其删除,查询需要1秒钟。
我的第一个想法是看看我是否可以通过将整个事物分解为CTE来降低ViewA中的行数,但这不会产生任何影响。我想我需要索引TableB,因为它只是在连接中使用的一堆varchars。我现在将它更改为临时表,以便我可以索引它。我无法更改基础表和视图。索引临时表是一种很好的方法,还是有更好的解决方案。
编辑以添加有关现有索引的信息。现在唯一带有索引的是TableA.Id,它是PK和聚簇索引。 TableB有一个Id字段,但它不是PK。 ViewA未编入索引。
再次编辑以更正某些结构。 SubmitDate位于View中,而不是表格中。
这是一个非常基本的结构:
CREATE TABLE TableA
(
Id int NOT NULL PRIMARY KEY,
Section varchar(20) NULL,
Code varchar(20) NULL
)
CREATE TABLE TableB
(
Id int NOT NULL PRIMARY KEY,
Name varchar(20) NULL,
Code varchar(20) NULL,
Section varchar(20) NULL
)
CREATE TABLE TableC
(
Id int NOT NULL PRIMARY KEY,
Name varchar(20) NULL,
SubmitDate DateTime NOT NULL
)
CREATE TABLE TableD
(
Id int NOT NULL PRIMARY KEY,
Section varchar(20) NULL
)
CREATE VIEW ViewA
AS
SELECT c.Section, d.Name, c.SubmitDate
FROM TableC c
JOIN TableD d ON a.Id = b.Id
答案 0 :(得分:3)
一个改进是将where子句重写为sargable子句。如果没有索引并将查询更改为:
,请将索引添加到SubmitDate
FROM TableA
CROSS JOIN ViewA
INNER JOIN TableB on ViewA.Name = TableB.Name
AND TableA.Code = TableB.Code
AND TableA.Location = TableB.Location
WHERE
TableA.SubmitDate >=DATEADD(MONTH,DATEDIFF(MONTH,0,GETDATE())-1,0)
And TableA.SubmitDate < Dateadd(DAY, 1, DATEADD(MONTH,
DATEDIFF(MONTH, -1, GETDATE())-1, -1) )
还在Name
,Code
和Location
列添加非聚簇索引。