MS SQL:在 SELECT 中使用函数调用优化查询

Posted

技术标签:

【中文标题】MS SQL:在 SELECT 中使用函数调用优化查询【英文标题】:MS SQL: optimize query with function call in SELECT 【发布时间】:2014-04-29 09:50:47 【问题描述】:

假设我有 e 表 - 表 1、表 2 和表 3。 Table2 在 Table1 和 Table3 上有外键。表 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

它按我想要的方式工作,但是太慢了。我该如何优化呢? 任何优化都会有所帮助。

【问题讨论】:

【参考方案1】:

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

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

我不知道@strList = COALESCE(@strList + ' ', '') + CAST(Table3.Name AS VARCHAR) 是否不如FOR XML PATHSTUFF 将多行名称连接成一行,但你可以尝试一下。

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

试试这个:

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

给我留言。

【讨论】:

感谢您的回答。在查看本教程link 后,我在几个小时前提出了类似的解决方案。【参考方案2】:

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

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

所以,简而言之:

    创建一个新表 在插入数据时,调用拆分函数并将拆分数据插入到与主数据相关的新表中 更改任何选择语句以引用新表

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

【讨论】:

以上是关于MS SQL:在 SELECT 中使用函数调用优化查询的主要内容,如果未能解决你的问题,请参考以下文章

sql优化

ORACLE当中自定义函数性优化浅析

在 ORACLE 的 select 语句中从 PL/SQL 调用函数

从 MS SQL 中的 PHP PDO 存储过程中返回 Select *

MS-Access 获取字段值,通过 VBA 函数运行,并发送到 SQL

调用 T-SQL 表值函数比调用一次快多次?