sql server-MS sql:使用SELECT中的函数调用优化查询



假设我有e个表-表1、表2和表3。表2在表1和表3上具有外键。表2有"名称"字段。我想从Table3中选择Table1.id和所有匹配的名称(串联)。这是对的查询

CREATE FUNCTION dbo.concat_string(@Input int)
   RETURNS VARCHAR(8000)
BEGIN
DECLARE @strList VARCHAR(8000)
SELECT @strList = COALESCE(@strList + ' ', '') + CAST(Table3.Name AS VARCHAR)
    FROM Table1
        JOIN Table2 ON Table2.Table1_ID = Table1.ID
        JOIN Table3 ON Table3.ID = Table2.Table3_ID
    WHERE
        Table1.ID = @Input
RETURN @strList;
END
SELECT Table1.ID, Table4.cc
FROM Table1 JOIN
(SELECT Table1.ID dbo.concat_string(Table1.ID) as "cc" FROM Table1) Table4 
ON Table1.ID = Table4.cID

它按照我想要的方式工作,但太慢了。如何对此进行优化?任何优化都将是有益的。

这是因为您正在为Table1的每一行调用函数,因此会影响您的性能。

第二点是,您使用联接多次调用table1,这会增加一些时间。

我不知道@strList = COALESCE(@strList + ' ', '') + CAST(Table3.Name AS VARCHAR)是否比FOR XML PATHSTUFF更有效地将多行Name连接到一行中,但你可以尝试一下

此外,我建议您在不使用函数的情况下,在一个唯一的查询中完成所有工作(这不是最好的性能)。

试试这个:

SELECT
    t.ID
    ,STUFF((
        SELECT ' ,' + CAST(Table3.Name AS VARCHAR)
        FROM 
            Table1 as t1
            JOIN Table2 
                ON Table2.Table1_ID = Table1.ID
            JOIN Table3 
                ON Table3.ID = Table2.Table3_ID
        WHERE t1.ID = t.ID
        FOR XML PATH('')
    ), 1, 1, '') as "cc"
FROM 
    Table1 as t

给我留言。

您遇到了一个常见问题。存储可用于插入、更新、删除或选择的数据(OLTP与OLAP)。

如果您经常需要拆分数据并从中进行选择,我建议您在需要选择之前先存储已拆分的数据。您可以在插入数据时使用上述功能将数据拆分到一个单独的表中,也可以根据您需要的最新数据通过隔夜过程进行拆分。然后,如果需要额外的性能,您可以对拆分的数据进行索引。

简而言之:

  1. 创建新表
  2. 在插入数据时,调用split函数,并将拆分后的数据插入到与主数据相关的新表中
  3. 更改任何select语句以引用新表

这种方法的缺点是增加了对第二个表的维护。

最新更新