2010-12-14 34 views
1

我有一個應該只返回前10個結果非常大的查詢:查詢的總行數的

從選擇排名前10位的ProductId .....

的問題是,我也希望與沒有「前10位」的條件匹配的結果總數,但同時返回所有行(我們正在談論大約10萬條結果)的結果是不合適的。

有沒有辦法獲得受前一個查詢影響的行的總數,無論是在其中還是在後續的查詢中,都沒有再次運行它?

PS:請100個000行:))

回答

4

沒有臨時表傾倒在一個變量的數量和返回

​​
+0

這有效地運行查詢兩次 - 一次獲得計數,一次獲得前10個結果。有沒有辦法避免運行兩次?它的執行時間爲幾秒 – 2010-12-14 13:01:04

+0

沒有,如果你想要的總行數,但100000行不是很多行,是非常廣泛的表,更重要的是你的where子句由索引覆蓋..也是你在計數查詢中不需要ORDER BY – SQLMenace 2010-12-14 13:04:32

+0

它是一個寬表,它執行大量連接和大量過濾。我擔心它會盡可能優化。我只是希望不要兩次運行它 – 2010-12-14 13:08:09

0

我想你可以爲聯合攻擊它選擇

select top 10 ... from ... where ... 
union 
select count(*) from ... where ... 

爲了避免這種類型的黑客攻擊,您需要向計數查詢添加虛假列,以便返回與主查詢相同數量的列。例如:

select top 10 id, first_name from people 
union 
select count(*), '' as first_name from people 

我不推薦使用此解決方案。使用兩個單獨的查詢是如何應該做

+0

我不確定這是否不會執行查詢兩次 – 2010-12-14 13:15:42

+0

返回的結果集將因爲您正在添加的第11行而改變。 – SnatchFrigate 2010-12-14 13:28:39

+0

從本質上講,它確實運行了兩個查詢,你不能在一個查詢中做你想要做的事情,最終在你的應用程序中你可以運行兩個查詢或者運行一個同樣的事情。 我不確定union是否可以在oracle之外使用。這隻會讓您選擇運行兩個單獨的查詢。 – SnatchFrigate 2010-12-14 13:36:59

0

一般來說沒有 - 推理如下:

如果查詢規劃可利用的TOP 10只返回10行,然後(!) RDBMS甚至不知道滿足全部條件的確切行數,它只是獲得TOP 10。

因此,當您想要找出滿足條件的所有行的計數時,您沒有運行第二次,但第一次。

說了適當的索引可能會使兩個查詢執行相當快。

編輯
MySQL有SQL_CALC_FOUND_ROWS返回,如果有應用無極限的查詢將返回的行數 - 谷歌搜索在MS SQL點分析SQL和CTE變等效,看到this forum(即使不確定要麼有資格運行它只有一次,但隨時檢查 - 並讓我們知道)。

2

假設您已經使用了ORDER BY子句(以正確定義哪些「TOP 10」結果),那麼您還可以添加ROW_NUMBER的調用,並使用相反的排序順序,並選擇最高值回。

例如,以下內容:

select top 10 *,ROW_NUMBER() OVER (order by id desc) from sysobjects order by ID 

擁有2001個值,2000年,1999年等一最後一欄,降。以下內容:

select COUNT(*) from sysobjects 

確認sysobjects中有2001行。

+1

這是一個很好的解決方案,但你也可以使用COUNT而不是ROW_NUMBER,所以你不必兩次訂購表格。 從sysobjects中選擇top 10 *,COUNT(*)OVER()ID – Lamak 2010-12-14 14:01:14

+0

@Lamak - 如果您願意,您可以自己添加該答案。我總是忘記'COUNT(*)OVER()' – 2010-12-14 14:05:05

+0

是的,我相信你的回答是正確的,它應該被接受,這就是爲什麼我沒有發佈我的,它的基本相同。 – Lamak 2010-12-14 14:08:38