对于同一查询中的不同输入变量,我想多次使用相同的表函数连接。但是,在我的情况下,这比使用表变量和分别从表函数中选择要慢得多。
如何避免表变量并且仍然有快速查询?
例如,我们有一个像
这样的SQL查询SELECT P.ProjectName, A.Number, B.Number FROM Project AS P LEFT JOIN dbo.fn_ProjectNumber(@dateA) AS A ON P.ProjectID = A.ProjectID LEFT JOIN dbo.fn_ProjectNumber(@dateB) AS B ON P.ProjectID = B.ProjectID
但它比从函数中单独选择变量然后稍后加入要慢得多,例如:
INSERT INTO @tempA SELECT P.ProjectID, A.Number FROM Project AS P LEFT JOIN dbo.fn_ProjectNumber(@dateA) AS A ON P.ProjectID = A.ProjectID INSERT INTO @tempB SELECT P.ProjectID, B.Number FROM Project AS P LEFT JOIN dbo.fn_ProjectNumber(@dateB) AS B ON P.ProjectID = B.ProjectID SELECT P.ProjectName, A.Number, B.Number FROM Project AS P LEFT JOIN @tempA AS A ON P.ProjectID = A.ProjectID LEFT JOIN @tempA AS B ON P.ProjectID = B.ProjectID
这可能是什么原因?有没有办法可以快速查询并避免表变量?
更多详情:
这只是一个类似于我正在做的例子,但函数fn_ProjectNumber(@date datetime)
将包含四个表之间的连接...
答案 0 :(得分:1)
尝试修复连接,在第二个LEFT JOIN中引用错误的别名:
ORIGINAL:
SELECT P.ProjectName, A.Number, B.Number
FROM Project AS P
LEFT JOIN dbo.fn_ProjectNumber(@dateA) AS A
ON P.ProjectID = A.ProjectID
LEFT JOIN dbo.fn_ProjectNumber(@dateB) AS B
ON P.ProjectID = A.ProjectID
FIXED:
SELECT P.ProjectName, A.Number, B.Number
FROM Project AS P
LEFT JOIN dbo.fn_ProjectNumber(@dateA) AS A
ON P.ProjectID = A.ProjectID
LEFT JOIN dbo.fn_ProjectNumber(@dateB) AS B
ON P.ProjectID = B.ProjectID --<<<<<
答案 1 :(得分:1)
您是否有任何特殊原因试图避免表变量?它们可以是一种很好的优化技术,不会留下任何临时对象进行清理。
无论如何,如果你不想这样做,你总是可以尝试
SELECT
P.ProjectID, A.Number, B.Number
FROM
Project AS P
LEFT JOIN
(SELECT P.ProjectID, A.Number
FROM Project AS P
LEFT JOIN dbo.fn_ProjectNumber(@dateA) AS A
ON P.ProjectID = A.ProjectID
) AS A
ON P.ProjectID = A.ProjectID
LEFT JOIN
(SELECT P.ProjectID, B.Number
FROM Project AS P
LEFT JOIN dbo.fn_ProjectNumber(@dateB) AS B
ON P.ProjectID = B.ProjectID
) AS B
ON P.ProjectID = B.ProjectID
答案 2 :(得分:1)
连接很慢,因为在您的示例查询中,您为表Project中的每一行调用一次函数。临时表的速度更快,因为你只调用一次函数。
避免临时表的一种方法是使用CTE(公共表表达式 - 它们不仅仅用于递归 - 在SQL 2005及更高版本中可用)。一般语法如下:
WITH cteTempName (<list of columns>)
as (<your table function call>)
SELECT <your query here, with "cteTempName" appearing as just another table to select from>
答案 3 :(得分:0)
可能连接速度较慢,因为您没有定义连接在一起的表之间的关系? 我对SQL Server中的查询性能了解不多,但定义关系将提高连接的性能。