我继承了一个存储过程,该存储过程在八个表中执行连接,其中一些表包含数十万行,然后从该连接的结果中选择前十个条目。
我在过程开始时有足够的信息从一个表中选择那十行,然后在这十行上执行这些连接,而不是在数十万个中间行上执行。
如何选择那些前十行,然后只对这十行进行连接,而不是在表中的所有数千行中执行连接?
答案 0 :(得分:9)
我应该尝试:
SELECT * FROM
(SELECT TOP 10 * FROM your_table
ORDER BY your_condition) p
INNER JOIN second_table t
ON p.field = t.field
答案 1 :(得分:1)
如果您的查询过于复杂,查询计划优化程序可能会在时间上找不到合适的计划。它只给出了几百毫秒,即使只有几个连接,也可能有数千种不同的方式来执行查询(不同的连接顺序等)。如果是这种情况,您将首先将前10行存储在临时表中,然后再使用它,如下所示:
select top 10 *
into #MainResults
from MyTable
order by your_condition;
select *
from #MainResults r
join othertable t
on t.whatever = r.whatever;
我已经看到第二种方法产生了巨大差异的情况。
答案 2 :(得分:0)
您还可以使用CTE定义顶部X,然后使用它
例如,此data.se query仅限于前40个代码
with top40 as (
select top 40 t.id, t.tagname
from tags t, posttags pt
where pt.tagid = t.id
group by t.tagname, t.id
order by count(pt.postid) desc
),
myanswers as(
select p.parentid, p.score
from posts p
where
p.owneruserid = ##UserID## and
p.communityowneddate is null
)
select t40.tagname as 'Tag', sum(p1.score) as 'Score',
case when sum(p1.score) >= 15 then ':-)' else ':-(' end as 'Status'
from top40 t40, myanswers p1, posttags pt1
where
pt1.postid = p1.parentid and
pt1.tagid = t40.id
group by t40.tagname
order by sum(p1.score) desc