SqlDataReader 循环行的速度不一致

问题描述 投票:0回答:1

我有一个 .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

非常感谢任何可能导致这些差异的想法。

.net sql-server vb.net sqldatareader
1个回答
0
投票

看来您在行中使用

DATEFROMPARTS(9999, 1, 1)
导致您的 SQL 计划使用逐行处理。当存在需要转换的数据类型不匹配或需要在比较期间执行函数时,可能会发生这种情况。

因为您始终将相同的值存储在变量中,然后使用该变量。

如果您在 SSMS 中执行它并且查看执行计划,您可能会看到它提到它

© www.soinside.com 2019 - 2024. All rights reserved.