减少 SUM(DATALENGTH()) 对链接服务器的影响

Jos*_*mar 4 sql-server linked-server

我有一个查询,它会向我报告添加记录所用的时间。我还在此查询中跟踪添加到数据库中的图像的大小。从我所见,它看起来像是从链接服务器返回整个图像,然后计算大小。有没有一种简单的方法可以让我在链接的另一侧计算大小,以便更快地返回?

SELECT
    [Date] = CAST(DATEADD(DAY,-@DaysBack,GETDATE()) AS DATE)
    ,NOTES = N.RPMID
    ,TimeTaken = DATEDIFF("SECOND",SN.PickedUpDate,SN.ProcessedDate)
    ,PictureSize = SUM(CAST(DATALENGTH(SI.[Image])AS BIGINT))
    ,RecordsAdded = CAST(COUNT(*) AS BIGINT)
FROM
    DBServer1.DB1.dbo.Notes AS N WITH (NOLOCK)
    INNER JOIN DBServer1.DB1.dbo.NoteDistribution AS ND WITH (NOLOCK) ON N.Notes=ND.Notes
    INNER JOIN dbo.Submission_Notes AS SN WITH (NOLOCK) ON SN.RetailPlanGuid=N.RPMID
    LEFT JOIN DBServer1.DB1.dbo.SavedImage SI WITH (NOLOCK) ON SI.Notes=N.Notes
WHERE
    1=1
    AND N.RecordStampWhenAdd > CAST(GETDATE()-@DaysBack AS DATE)
    AND N.RecordStampWhenAdd < CAST(GETDATE()-@DaysBack+1 AS DATE)
    AND DATEDIFF("SECOND",SN.PickedUpDate,SN.ProcessedDate) > 0
GROUP BY
    N.RPMID
    ,DATEDIFF("SECOND",SN.PickedUpDate,SN.ProcessedDate)
Run Code Online (Sandbox Code Playgroud)

有问题的部分是返回的图片大小。我希望那里的计算在存储数据的服务器上完成,然后将数字返回给我。对此的任何帮助都会很棒。谢谢。

Aar*_*and 6

我不确定您是如何确定所有数据都通过网络传输的(或为什么会这样),但您始终可以有一个计算列:

ALTER TABLE dbo.SavedImage ADD PictureSize 
  AS CAST(DATALENGTH([Image]) AS BIGINT);
Run Code Online (Sandbox Code Playgroud)

或者只需添加一列并在您插入/更新行时自己计算,要么通过存储过程强制插入/更新,要么使用触发器。

并根据需要坚持和/或索引,然后SUM(PictureSize)在查询中使用。

当然,最大的影响仍然是您必须扫描整个表或索引才能生成聚合。

这种方法也可用于维护其他一些表中所有列的总大小,但我主要反对物化冗余数据,除非这样做有明显的优势。

无论如何,我真的不认为这个查询很慢,因为它通过网络移动整个 varbinary 数据,然后在错误的一端计算长度;如果您有证据表明情况确实如此,请更新问题,我们会尽力解决。