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 PATH
和STUFF
将多行名称连接成一行,但你可以尝试一下。
另外,我建议您在不使用函数的情况下在唯一的查询中完成所有工作(不是最好的性能)。
试试这个:
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 中使用函数调用优化查询的主要内容,如果未能解决你的问题,请参考以下文章
在 ORACLE 的 select 语句中从 PL/SQL 调用函数
从 MS SQL 中的 PHP PDO 存储过程中返回 Select *