我想到MSSQL数据库进行一次往返,以检索多个表。每个表都以某种方式依赖于相同的昂贵查找,这将获取一堆ID并处理分页和非常基本的过滤。所以我试图将昂贵的部分移出,所以它只发生一次,然后重复使用它的结果集。
下面是我正在努力做的一个非常简化的版本。 “主要查询”是昂贵的查找,它对于它下面的下一个其他查询很常见。 “第一个结果集”应该按照您的预期返回我想要的内容,但“第二个结果集”会因为主查询超出范围而失败。
-- Primary query
WITH t(ItemId, Row) AS (
SELECT ItemId, ROW_NUMBER() OVER(ORDER BY DateCreated DESC) AS Row
FROM Items
)
-- First result set
SELECT *
FROM Items
INNER JOIN t ON Items.ItemId = t.ItemId
WHERE t.Row < 10
-- Second result set
SELECT *
FROM Photos
INNER JOIN ItemPhotos ON Photos.PhotoId = ItemPhotos.PhotoId
INNER JOIN t ON ItemPhotos.ItemId = t.ItemId
WHERE t.Row < 10
有没有办法做到这一点,以便第二个结果集有效?
我想避免创建临时表,因为根据我的经验,我几乎总是有一个更便宜的替代品,我还没有学到。在这种情况下,我不确定是否有替代方案,但我希望有人知道解决方法。 (我当然会对它们进行测试。)
我知道在上面的示例中,您可以通过对整个事情执行INNER JOIN
来返回单个结果集,但在我的情况下,它不是一个可行的解决方案,因为结果集会很大。
答案 0 :(得分:3)
不,没有办法做到这一点。
答案 1 :(得分:0)
如果您不想使用临时表,可以使用如下变量表:(由于Aaron感谢错误而更改)
宣布@mytable(......)
答案 2 :(得分:0)
正如我的评论中所述,即使该语法有效,它也无法达到单次访问数据库的目的,因为CTE只是语法。
鉴于t.Row&gt; 1740 AND t.Row&lt; = 1760我会把#temp放在临时表上 我喜欢临时表的简单性,但它不能很好地查询优化
这假设ItemID是PK
如果要创建#temp,则在其中放置一些结构,以使连接尽可能高效。
插入中的顺序将最小化(或消除)PK上的碎片
连接中的#temp.rn而不是where使查询优化器有机会在连接之前进行过滤
IF OBJECT_ID(N'tempdb..#temp', N'U') IS NOT NULL DROP TABLE #temp;
CREATE TABLE #temp (ItemId INT PRIMARY KEY CLUSTERED, rn INT);
insert into #temp
SELECT sID, ROW_NUMBER() OVER(ORDER BY addDate DESC) AS Row
FROM docSVsys
where sID < 10000
ORDER by sID;
select count(*) from #temp;
CREATE UNIQUE NONCLUSTERED INDEX [IX] ON #temp ([rn] ASC);
select docSVtext.value
from docSVtext
join #temp
on docSVtext.sID = #temp.ItemID
and #temp.rn >= 100
and #temp.rn < 200;
select docSVdate.value
from docSVdate
join #temp
on docSVdate.sID = #temp.ItemID
and #temp.rn >= 100
and #temp.rn < 200;
IF OBJECT_ID(N'tempdb..#temp', N'U') IS NOT NULL DROP TABLE #temp;
另一个选项是#temp2,您可以为单个条件连接插入行。