我繼承了一個存儲過程執行跨八張桌子,其中一些含有幾百幾千行的連接「連接表中選擇前10名」,然後選擇頂部來自該連接結果的十個條目。「選擇前10名,然後加入表」,而不是
我必須在程序開始足夠的信息來從單一的表中選擇那些十行,然後執行這些加入那些十行,而不是成千上萬的中間排。
我該如何選擇那些十大行,然後只做加入那些十行,而不是執行連接所有的數千行的表中的?
我繼承了一個存儲過程執行跨八張桌子,其中一些含有幾百幾千行的連接「連接表中選擇前10名」,然後選擇頂部來自該連接結果的十個條目。「選擇前10名,然後加入表」,而不是
我必須在程序開始足夠的信息來從單一的表中選擇那些十行,然後執行這些加入那些十行,而不是成千上萬的中間排。
我該如何選擇那些十大行,然後只做加入那些十行,而不是執行連接所有的數千行的表中的?
我應該嘗試:
SELECT * FROM
(SELECT TOP 10 * FROM your_table
ORDER BY your_condition) p
INNER JOIN second_table t
ON p.field = t.field
你也可以使用一個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
這相當於marco的答案; CTE只是嵌套子查詢的更優雅的語法。 (有一些例外,但在這種情況下是這樣)。 –
如果你查詢是足夠複雜,查詢計劃優化器可以運行的時間找到一個很好的計劃。它只有幾百毫秒,並且即使有幾個連接,也可能有成千上萬種不同的方式來執行查詢(不同的連接命令等)。如果是這樣的話,你會從先在一個臨時表中存儲的前10行,然後使用中獲益,後來是這樣的:
select top 10 *
into #MainResults
from MyTable
order by your_condition;
select *
from #MainResults r
join othertable t
on t.whatever = r.whatever;
我在哪裏見過這第二種方法已經取得了巨大的情況下,區別。
嗯,我幾乎總是有相反的經歷。將臨時錶轉換爲內聯視圖,CTE或普通舊聯接比臨時表更好 –
完全取決於規模。如果行數很少(在這種情況下是10),這可能是值得的。如果他們開始變得更高,那麼它就不值得。 –
Normalyl的uery優化做到這一點。檢查執行計劃 - 您可能在這裏完全沒有問題。 – TomTom
查詢返回用戶所處理的最後十條記錄。出現這個問題的原因是,從事最多記錄的用戶看到了最糟糕的問題。我會承認,我可能會錯誤地看待問題,但這絕對不是問題 – Frosty840
是的,例如......都是獨立的嗎? – TomTom