我有一个 .NET 项目,在其中运行两个具有或多或少相同复杂性的 SQL 查询,即相同数量的 NULL 检查和 INNER 连接。
第一个
SqlDataReader
的执行时间比第二个要长得多,但这是由于查询的总行数不同造成的。第一个 SQL 查询还返回 18 列,而不是第二个 SQL 查询中的 14 列。
两个 SQL 数据集中返回的行数几乎相同 - 大约。 100,000 行。
循环访问这些行时,第一个读取器比第二个读取器快 15 倍:
行动 | 经过时间 |
---|---|
执行第一个读者 | 00:00:27.0845320 |
循环第一个读者的行 | 00:00:00.9528895 |
执行第二个读者 | 00:00:08.4737993 |
循环第二个读取器的行 | 00:00:14.0965122 |
我使用的 SQL 查询用于检索第二个读取器中的数据并循环遍历,是:
Using myConn = New SqlConnection(connectionString)
Dim myCmd = New SqlCommand(sqlCustomerPoint, myConn)
myCmd.Parameters.AddWithValue("@AreaLevel", SqlDbType.VarChar).Value = _AreaLevel
myCmd.Parameters.AddWithValue("@AreaName", SqlDbType.VarChar).Value = _AreaName
myCmd.CommandTimeout = 0
myConn.Open()
Using myReader As SqlDataReader = myCmd.ExecuteReader
If myReader.HasRows Then
Do While myReader.Read()
'Process the data
setCustomerPointDetails(myReader)
Loop
End If
End Using
End Using
即使注释掉循环中的代码 (setCustomerPointDetails(myReader)),循环也几乎花费相同的时间。
第二个 SqlDataReader 使用的 SQL 查询是
DECLARE @AreaLevel as CHAR(40) = 'District'
DECLARE @AreaName as CHAR(40) = 'Rotterdam'
SELECT
pnt.se_fld2_pointid2,
se_fld5_nodeid2,
pipe.se_fld0_id,
chain.se_fld2_chainid2,
pnt.se_fld14_coord.STX as se_fld14_coord_X,
pnt.se_fld14_coord.STY as se_fld14_coord_Y,
sp.se_fld50_sapid,
sp.se_fld67_street,
ISNULL(sp.se_fld71_housenumber, 0) as se_fld71_housenumber,
sp.se_fld70_city,
FROM Mainserver.history.se_hm2_t106_topologicalpoin as pnt
INNER JOIN Mainserver.history.se_hm2_t82_joint as j
ON j.se_fld33_rwoid2 = pnt.se_fld8_rwoid2
INNER JOIN VSDWHP.history.se_hm2_t96_servicepoint as sp
ON j.se_fld0_id = sp.se_fld61_jointid
INNER JOIN Mainserver.history.se_hm2_t103_topologicalchai as chain
ON (pnt.se_fld5_nodeid2 = chain.se_fld12_lastnodeid2)
INNER JOIN Mainserver.history.se_hm2_t85_mainsection as pipe
ON chain.se_fld15_rwoid2 = pipe.se_fld53_rwoid2
INNER JOIN
(
SELECT *
FROM Mainserver.Area
WHERE name = @AreaName and level = @AreaLevel
and Tot > DATEFROMPARTS(2098,1,1)
) as area
ON pnt.se_fld14_coord.STIntersects(area.Shape) = 1
WHERE
pnt.se_history_validto > DATEFROMPARTS(9999, 1, 1)
and j.se_history_validto > DATEFROMPARTS(9999, 1, 1)
and sp.se_history_validto > DATEFROMPARTS(9999, 1, 1)
and chain.se_history_validto > DATEFROMPARTS(9999, 1, 1)
and pipe.se_history_validto > DATEFROMPARTS(9999, 1, 1)
and sp.se_fld76_sapobjectstatus = 'In bedrijf'
and se_fld10_appcode = 5
非常感谢任何可能导致这些差异的想法。
看来您在行中使用
DATEFROMPARTS(9999, 1, 1)
导致您的 SQL 计划使用逐行处理。当存在需要转换的数据类型不匹配或需要在比较期间执行函数时,可能会发生这种情况。
因为您始终将相同的值存储在变量中,然后使用该变量。
如果您在 SSMS 中执行它并且查看执行计划,您可能会看到它提到它