为什么这两个查询的时间差异很大?
此查询大约需要51秒才能完成:
SELECT TOP 1000 *
FROM [PHONER].[dbo].[V_PhonerSubjects]
WHERE ProjectID = 137;
但是,此查询大约需要1秒钟才能完成:
SELECT TOP 1000 *
FROM [PHONER].[dbo].[V_PhonerSubjects]
WHERE ProjectID = 107;
注意:唯一的区别是密钥的值。
两者总共有超过1000条记录。项目107有26000条记录,项目137有4500条记录。
ProjectID
是一个索引主键。
我注意到第二个查询完成并在1秒内将所有行发送到结果窗口。第一个Query在大约3秒后开始发送行,并在大约51秒后完成。
这是视图V_PhonerSubjects
:
SELECT
dbo.PhonerEmner.PhonerEmID AS SubjectID, dbo.PhonerEmner.FK_ProID AS ProjectID,
dbo.PhonerProjekt.PhonerTitel AS ProjectName, dbo.Medlemsdata.Vennenr AS FriendNo,
dbo.Medlemsdata.OpretteDato AS CreatedDate, dbo.Medlemsdata.OpretteID AS CreatedID,
dbo.Bruger.Intialer AS CreatedBy, dbo.Medlemsdata.ÆndretDato AS ChangedDate,
dbo.Medlemsdata.ÆndretID AS ChangedID,
Bruger_3.Intialer AS ChangedBy,
ISNULL(dbo.Medlemsdata.Organisation, N'') + N' ' + ISNULL(dbo.Medlemsdata.Fornavn, N'') + N' ' + ISNULL(dbo.Medlemsdata.Efternavn, N'') AS Name,
dbo.MedlemsAdresse.AdrID AS AddressID, dbo.MedlemsAdresse.Adresse AS Address1,
dbo.MedlemsAdresse.Adresse2 AS Address2, dbo.MedlemsAdresse.Postnr AS ZIP,
dbo.Postnumre.[By] AS City, dbo.Medlemsdata.CPRnr AS CPRno,
dbo.Medlemsdata.Køn AS Gender, dbo.Medlemsdata.Telefon AS Phone01,
dbo.Medlemsdata.TlfNote1 AS Phone02Type, dbo.Medlemsdata.Tlf1 AS Phone02,
dbo.Medlemsdata.TlfNote2 AS Phone03Type, dbo.Medlemsdata.Tlf2 AS Phone03,
dbo.Medlemsdata.TlfNote3 AS Phone04Type,
dbo.Medlemsdata.Tlf3 AS Phone04, dbo.Medlemsdata.TlfSMS AS PhoneMobile,
dbo.Medlemsdata.[E-mail] AS Email, dbo.Medlemsdata.SPFelt1 AS SPField01,
dbo.Medlemsdata.SPFelt2 AS SPField02, dbo.Medlemsdata.SPFelt3 AS SPField03,
dbo.Medlemsdata.SPFelt4 AS SPField04, dbo.Medlemsdata.SPFelt5 AS SPField05,
dbo.Medlemsdata.SPFelt6 AS SPField06, dbo.Medlemsdata.SPFelt7 AS SPField07,
dbo.Medlemsdata.SPFelt8 AS SPField08, dbo.Medlemsdata.SPFelt9 AS SPField09,
dbo.Medlemsdata.SPFelt10 AS SPField10, dbo.Medlemsdata.SPFelt11 AS SPField11,
dbo.Medlemsdata.SPFelt12 AS SPField12, dbo.Medlemsdata.SPFelt13 AS SPField13,
dbo.Medlemsdata.SPFelt14 AS SPField14, dbo.PhonerEmner.SidsteKontakt AS LastContact,
dbo.PhonerEmner.AntalKontakt AS ContactTimes, dbo.PhonerEmner.KontaktDage AS ContactDays,
dbo.PhonerEmner.KontaktEfter AS ContactAfter,
dbo.PhonerEmner.PhonerIgen AS ContactAfterPhonerID,
Bruger_1.Navn AS ContactAfterPhonerName, dbo.PhonerEmner.PhonerNote,
dbo.PhonerEmner.Stemning AS Mood, dbo.PhonerEmner.Status,
dbo.PhonerEmner.PhonerAft AS LastPhonerID, Bruger_2.Navn AS LastPhonerName,
dbo.PhonerEmner.SlutNote AS EndNote, dbo.PhonerEmner.SlutDato AS EndDate,
dbo.PhonerImport.PhonerImportID AS ImportID, dbo.PhonerImportData.Status AS ImportStatus,
dbo.PhonerImport.ImportFileName, dbo.PhonerImport.ImportTime,
dbo.PhonerProjekt.SvarerIkkeTid
FROM
dbo.Bruger AS Bruger_1
RIGHT OUTER JOIN
dbo.PhonerProjekt
RIGHT OUTER JOIN
dbo.PhonerEmner ON dbo.PhonerProjekt.PhonerProID = dbo.PhonerEmner.FK_ProID
LEFT OUTER JOIN
dbo.PhonerImportData ON dbo.PhonerEmner.PhonerEmID = dbo.PhonerImportData.FK_PhonerEmID
LEFT OUTER JOIN
dbo.Bruger AS Bruger_2 ON dbo.PhonerEmner.PhonerAft = Bruger_2.BrugerID ON Bruger_1.BrugerID = dbo.PhonerEmner.PhonerIgen
LEFT OUTER JOIN
dbo.Bruger
RIGHT OUTER JOIN
dbo.Bruger AS Bruger_3
RIGHT OUTER JOIN
dbo.Medlemsdata ON Bruger_3.BrugerID = dbo.Medlemsdata.ÆndretID ON dbo.Bruger.BrugerID = dbo.Medlemsdata.OpretteID ON dbo.PhonerEmner.FK_Vennenr = dbo.Medlemsdata.Vennenr
LEFT OUTER JOIN
dbo.Postnumre
RIGHT OUTER JOIN
dbo.MedlemsAdresse ON dbo.Postnumre.Postnummer = dbo.MedlemsAdresse.Postnr ON dbo.Medlemsdata.FK_AdrID = dbo.MedlemsAdresse.AdrID
LEFT OUTER JOIN
dbo.PhonerImport ON dbo.PhonerImportData.FK_PhonerImportID = dbo.PhonerImport.PhonerImportID
项目107的客户统计数据:
Client Execution Time 14:04:24
Query Profile Statistics
Number of INSERT, DELETE and UPDATE statements 0 0.0000
Rows affected by INSERT, DELETE, or UPDATE statements 0 0.0000
Number of SELECT statements 2 2.0000
Rows returned by SELECT statements 1001 1001.0000
Number of transactions 0 0.0000
Network Statistics
Number of server roundtrips 3 3.0000
TDS packets sent from client 3 3.0000
TDS packets received from server 241 241.0000
Bytes sent from client 340 340.0000
Bytes received from server 976874 976874.0000
Time Statistics
Client processing time 95 95.0000
Total execution time 391 391.0000
Wait time on server replies 296 296.0000
项目137的客户统计数据:
Client Execution Time 13:58:28
Query Profile Statistics
Number of INSERT, DELETE and UPDATE statements 0 0.0000
Rows affected by INSERT, DELETE, or UPDATE statements 0 0.0000
Number of SELECT statements 2 2.0000
Rows returned by SELECT statements 1001 1001.0000
Number of transactions 0 0.0000
Network Statistics
Number of server roundtrips 3 3.0000
TDS packets sent from client 3 3.0000
TDS packets received from server 217 217.0000
Bytes sent from client 340 340.0000
Bytes received from server 877700 877700.0000
Time Statistics
Client processing time 129596 129596.0000
Total execution time 130297 130297.0000
Wait time on server replies 701 701.0000
答案 0 :(得分:1)
左右连接的复杂混乱以及查询的非关联可读性很可能是问题的一部分。我可能完全错了并接受了。但是,我根据从每个表到下一个表的所有分层连接条件重新构建了查询...每个表“JOIN”ed和“ON”条件直接作为关联vs混合。在这里,您可以分层次地查看表格与获取必要详细信息之间的关系。我还使用ALIASES从原始帖子中获得更好的可读性。
因此,您似乎有一些电话项目加入了PhonerEmner表。基于这些元素,您尝试尽可能多地查找辅助数据。如果它存在,很好,得到它,但如果在子级相关表中找不到这样的记录,则不要停止。这样,它们都是LEFT JOIN。如果您希望在任何给定表中记录是必需的,只需从LEFT JOIN更改为INNER JOIN,和/或添加WHERE子句以确保找到给定的alias.ID列。
所有这一切,我会确保表有索引,以通过..
正确优化连接table index
PhonerEmner (FK_ProID, PhonerIgen, PhonerEmID, PhonerAft, FK_Vennenr
PhonerProjekt (PhonerProID)
Bruger (BrugerID
PhonerImportData (FK_PhonerEmID, FK_PhonerImportID
PhonerImport (PhonerImportID
Medlemsdata (Vennenr, OpretteID, ÆndretID, FK_AdrID )
MedlemsAdresse (AdrID, Postnr)
Postnumre (Postnummer)
并提出了这个修改过的查询,您可以创建一个新的View来进行测试。
SELECT
PE.PhonerEmID AS SubjectID,
PE.FK_ProID AS ProjectID,
PP.PhonerTitel AS ProjectName,
MED.Vennenr AS FriendNo,
MED.OpretteDato AS CreatedDate,
MED.OpretteID AS CreatedID,
B.Intialer AS CreatedBy,
MED.ÆndretDato AS ChangedDate,
MED.ÆndretID AS ChangedID,
B3.Intialer AS ChangedBy,
ISNULL(MED.Organisation, N'')
+ N' ' + ISNULL(MED.Fornavn, N'')
+ N' ' + ISNULL(MED.Efternavn, N'') AS Name,
ADR.AdrID AS AddressID,
ADR.Adresse AS Address1,
ADR.Adresse2 AS Address2,
ADR.Postnr AS ZIP,
PST.[By] AS City,
MED.CPRnr AS CPRno,
MED.Køn AS Gender,
MED.Telefon AS Phone01,
MED.TlfNote1 AS Phone02Type,
MED.Tlf1 AS Phone02,
MED.TlfNote2 AS Phone03Type,
MED.Tlf2 AS Phone03,
MED.TlfNote3 AS Phone04Type,
MED.Tlf3 AS Phone04,
MED.TlfSMS AS PhoneMobile,
MED.[E-mail] AS Email,
MED.SPFelt1 AS SPField01,
MED.SPFelt2 AS SPField02,
MED.SPFelt3 AS SPField03,
MED.SPFelt4 AS SPField04,
MED.SPFelt5 AS SPField05,
MED.SPFelt6 AS SPField06,
MED.SPFelt7 AS SPField07,
MED.SPFelt8 AS SPField08,
MED.SPFelt9 AS SPField09,
MED.SPFelt10 AS SPField10,
MED.SPFelt11 AS SPField11,
MED.SPFelt12 AS SPField12,
MED.SPFelt13 AS SPField13,
MED.SPFelt14 AS SPField14,
PE.SidsteKontakt AS LastContact,
PE.AntalKontakt AS ContactTimes,
PE.KontaktDage AS ContactDays,
PE.KontaktEfter AS ContactAfter,
PE.PhonerIgen AS ContactAfterPhonerID,
B1.Navn AS ContactAfterPhonerName,
PE.PhonerNote,
PE.Stemning AS Mood,
PE.Status,
PE.PhonerAft AS LastPhonerID,
B2.Navn AS LastPhonerName,
PE.SlutNote AS EndNote,
PE.SlutDato AS EndDate,
PI.PhonerImportID AS ImportID,
PID.Status AS ImportStatus,
PI.ImportFileName, PI.ImportTime,
PP.SvarerIkkeTid
FROM
dbo.PhonerEmner PE
LEFT JOIN dbo.PhonerProjekt PP
ON PE.FK_ProID = PP.PhonerProID
LEFT JOIN dbo.Bruger B1
ON PE.PhonerIgen = B1.BrugerID
LEFT JOIN dbo.PhonerImportData PID
ON PE.PhonerEmID = PID.FK_PhonerEmID
LEFT JOIN dbo.PhonerImport PI
ON PID.FK_PhonerImportID = PI.PhonerImportID
LEFT JOIN dbo.Bruger B2
ON PE.PhonerAft = B2.BrugerID
LEFT JOIN dbo.Medlemsdata MED
ON PE.FK_Vennenr = MED.Vennenr
LEFT JOIN dbo.Bruger B
ON MED.OpretteID = B.BrugerID
LEFT JOIN dbo.Bruger B3
ON MED.ÆndretID = B3.BrugerID
LEFT JOIN dbo.MedlemsAdresse ADR
ON MED.FK_AdrID = ADR.AdrID
LEFT JOIN dbo.Postnumre PST
ON ADR.Postnr = PST.Postnummer
答案 1 :(得分:0)
鉴于行数越少,我就会怀疑数据内容,而不是架构。
如果一个数据集在大多数OUTER JOIN上找到匹配而另一个没有,那么这可能会解释运行时的一些差异。加入时,未命中只会对索引进行ping操作,但是命中会导致表格读取。
答案 2 :(得分:0)
我发现了问题。
我改变了联接。对我而言,无论我是以某种方式做到这一点都应该无关紧要,但显然它确实如此。
而不是将PhonerEmner连接到PhonerEmID = FK_PhonerEmID上的PhonerImportData。我在Vennenr = FK_Vennenr上将MedlemsData加入了PhonerImportData。它必须与PhonerEmID有关,而不是主键但只是索引。