重用选择子查询/结果

Posted

技术标签:

【中文标题】重用选择子查询/结果【英文标题】:Resusing select subquery/result 【发布时间】:2010-11-30 12:00:01 【问题描述】:

我正在尝试优化使用冗余查询块的查询的速度。我正在尝试使用下面的查询在 sql server 2008 中进行逐行联接。

Select * from 
(<complex subquery>) cq
join table1 t1 on (cq.id=t1.id)
union
Select * from  
<complex subquery> cq
join table2 t2 on (cq.id=t2.id)

&lt;complex subquery&gt; 在两个联合子查询片段上完全相同,只是我们需要将它与多个不同的表连接以获得相同的列数据。

有什么方法可以在不使用临时表缓存结果的情况下重写查询以使其更快?

【问题讨论】:

CTE 的可能?谷歌一下,看看它是否符合您的需求。 @leppie - 如果不使用此处所述的计划指南,CTE 通常不会实现结果explainextended.com/2009/05/28/generating-xml-in-subqueries 【参考方案1】:

为什么不使用临时表,看看这是否能提高执行统计数据?

在某些情况下,查询优化器会自动向缓存子查询的计划添加一个假脱机,但这基本上只是一个临时表。

您是否检查过当前计划以确保查询实际上被多次评估?

【讨论】:

临时表是要走的路,即使您可能需要确保不会破坏您的 tempdb 从而减慢数据库的其余部分。 上述查询用于搜索框,这意味着在目前的用户负载下,我们将在每秒 100 到 1000 次之间的任何地方触发此查询...您认为 tempDb 可以处理吗那个?【参考方案2】:

如果没有具体示例,很难提供帮助,但请尝试使用 WITH 语句,例如:

WITH csq(x,y,z) AS (
  <complex subquery>
)
Select * from 
 csq
join table1 t1 on (cq.id=t1.id)
union
Select * from  
 csq
join table2 t2 on (cq.id=t2.id)

它有时会加快速度

【讨论】:

【参考方案3】:

您的查询的性质是否允许您反转它?不是“(加入,加入)联合”,而是“(联合)加入”?喜欢:

Select * from
(<complex subquery>) cq
join (
    Select * from table1 t1
    union 
    Select * from table2 t2
) ts
on cq.id=ts.id

我不确定你的复杂查询的双重评估是否真的有问题。但是,根据您的问题,这将是一种鼓励 SQL 仅评估 &lt;complex query&gt; 一次的查询形式。

【讨论】:

不幸的是,不是......复杂查询的结果在 sql union sn-ps 中都是必需的......是的,我试图避免对复杂子查询进行多次评估

以上是关于重用选择子查询/结果的主要内容,如果未能解决你的问题,请参考以下文章

sql子查询

MYSQL基础九--子查询和连接

重用选择子查询/结果

如果子查询没有返回结果,为啥“= ALL(子查询)”评估为真?

在 WHERE 子句中重用选择表达式的子查询

(My)SQL:如果子查询不是空集,则返回子查询