sql tvp 与 xml 存储过程中的速度相同???我的测试或逻辑有缺陷吗?

sql tvp vs xml speed in stored procedure are the same??? Is my testing or logic flawed?

我是一名意外的 DBA,负责加速我们所有的 sql 服务器。我有一个使用率很高的查询,平均工作时间很糟糕。我注意到它使用 XML 将数据传递给存储过程。查询计划告诉我它大部分时间都花在转换 XML 上。我读过的所有内容都说 XML 比 TVP 慢 33%。我使用 TVP 重写了 SP,并使用以下方法比较了时间:

SELECT @StartTime=GETDATE() 
exec GetTVPData3 @tvp  --or XML method
SELECT @EndTime=GETDATE()
SELECT DATEDIFF(ms,@StartTime,@EndTime) AS [Duration in millisecs] 

经过许多 运行 秒并计算出时间的平均值.... TVP vs XML XML 赢了 5 毫秒。 ???? (550 毫秒对 545 毫秒)我的测试或逻辑有缺陷吗?

XML 和 TVP 都在我获得 StartTime 之前填充。我已经 运行 在 2 个不同的 SQL 测试服务器上进行了类似的测试。

交叉应用中使用了特定代码。 SP 的唯一区别是:

**TVP**
CROSS APPLY (SELECT id AS ProductID, sortorder AS SortOrder  FROM @Insert_tvp) Items

**XML**
CROSS APPLY (
SELECT f.id.value('@id', 'int') AS ProductID, f.id.value('@sortorder', 'int') AS SortOrder
FROM @ProductIDs.nodes('list/p')
AS f(id)
) Items

我脑子里的一切都告诉我,我们需要改用 TVP 并摆脱 XML。但如果没有更好的结果,我无法说服编码人员。

编辑:添加整个 XML SP:

ALTER PROCEDURE [dbo].[ExtendedDataXML]

@HostedSiteID INT,
@ProductIDs XML = NULL,
@ImageType VARCHAR(20) = NULL
AS
BEGIN

SET NOCOUNT ON;

SELECT
    Products.ID AS ItemID,
    0 AS ItemType,
    Products.SKU,
    Products.Title,
    HSP.Slug,
    Products.Rank,
    Products.Rank AS SalesRank,
    Products.Status,
    Products.LaunchDate,
    Products.IsOnline,
    Products.IsAutoOffline,
    Products.IsSalableOnline,
    Products.IsMarketableOnline,
    Products.LeadIn, Products.LeadOut,
    COALESCE(Products.CaseQuantity, 1) AS CaseQuantity,
    COALESCE(Products.MinimumOrderQuantity, 1) AS MinimumOrderQuantity,
    Products.QuantityOnHand,
    Image.Filename, Image.Width, Image.Height, Image.Alt, Image.Title,
    Pricing.Price, Pricing.SalePrice,
    Products.TruckShipment,
    HSP.NDescription
FROM Products
JOIN HostedSites_Products HSP ON Products.ID = HSP.ProductID
CROSS APPLY (
    SELECT f.id.value('@id', 'int') AS ProductID, f.id.value('@sortorder', 'int') AS SortOrder
    FROM @ProductIDs.nodes('list/p')
    AS f(id)
) Items
OUTER APPLY (
    SELECT TOP(1) Filename, Width, Height, Alt, Title
    FROM Items_Images
    JOIN Images ON Items_Images.ImageID = Images.ID
    WHERE Items_Images.ItemID = Products.ID
    AND Items_Images.ItemType = 0
    AND Images.Type = COALESCE(@ImageType, '.4b')
) Image
OUTER APPLY (
    SELECT TOP(1) Price, SalePrice, CurrentPrice
    FROM ProductPrices
    WHERE ProductPrices.ProductID = Products.ID
    ORDER BY LoRange ASC
) Pricing
WHERE Products.ID = Items.ProductID
AND HSP.HostedSiteID = @HostedSiteID
AND HSP.Validated = 1
AND Products.IsMarketableOnline = 1
ORDER BY Items.SortOrder
END

CROSS APPLY 表示按行执行!您正在一遍又一遍地解析您的 XML...

据我所知,您的 ID 列表是过滤器

除此之外,在内联 TVF 中这样做效果更好(没有 BEGIN...END 的语法,您可以这样尝试:

ALTER PROCEDURE [dbo].[ExtendedDataXML]

@HostedSiteID INT,
@ProductIDs XML = NULL,
@ImageType VARCHAR(20) = NULL
AS
BEGIN

    SET NOCOUNT ON;
    WITH IDList AS
    (
        SELECT f.id.value('@id', 'int') AS ProductID, f.id.value('@sortorder', 'int') AS SortOrder
        FROM @ProductIDs.nodes('list/p') AS f(id)
    )
    SELECT
        Products.ID AS ItemID,
        0 AS ItemType,
        Products.SKU,
        Products.Title,
        HSP.Slug,
        Products.Rank,
        Products.Rank AS SalesRank,
        Products.Status,
        Products.LaunchDate,
        Products.IsOnline,
        Products.IsAutoOffline,
        Products.IsSalableOnline,
        Products.IsMarketableOnline,
        Products.LeadIn, Products.LeadOut,
        COALESCE(Products.CaseQuantity, 1) AS CaseQuantity,
        COALESCE(Products.MinimumOrderQuantity, 1) AS MinimumOrderQuantity,
        Products.QuantityOnHand,
        Image.Filename, Image.Width, Image.Height, Image.Alt, Image.Title,
        Pricing.Price, Pricing.SalePrice,
        Products.TruckShipment,
        HSP.NDescription
    FROM Products
    JOIN HostedSites_Products HSP ON HSP.HostedSiteID = @HostedSiteID AND HSP.Validated = 1 AND Products.ID = HSP.ProductID
    INNER JOIN IDList AS Items ON Items.ProductID=Products.ProductID
    OUTER APPLY (
        SELECT TOP(1) Filename, Width, Height, Alt, Title
        FROM Items_Images
        JOIN Images ON Items_Images.ImageID = Images.ID
        WHERE Items_Images.ItemID = Products.ID
        AND Items_Images.ItemType = 0
        AND Images.Type = COALESCE(@ImageType, '.4b')
    ) Image
    OUTER APPLY (
        SELECT TOP(1) Price, SalePrice, CurrentPrice
        FROM ProductPrices
        WHERE ProductPrices.ProductID = Products.ID
        ORDER BY LoRange ASC
    ) Pricing
    WHERE Products.IsMarketableOnline = 1
    ORDER BY Items.SortOrder
END