2012-06-07 38 views
8

好吧,也許我太老了,我想了解以下內容。爲什麼一個工會比一個組的速度快

查詢1

select count(*), gender from customer 
group by gender 

查詢2.

select count(*), 'M' from customer 
where gender ='M' 
union 
select count(*), 'F' from customer 
where gender ='F' 

第一查詢是簡單的,但由於某些原因的探查,當我在同一時間執行兩個,它說,查詢2使用39%的時間,查詢1,61%。

我想了解原因,也許我必須重寫所有的查詢。

+1

只是一個猜測:第二個查詢實際上有沒有聚集,沒有狀態保持以計算計數(它只是返回匹配的行數'COUNT(*)') – lanzz

+0

你是什麼意思'在同一時間? – Sebas

+2

我想你只有2個性別和每個人都有分配,而不是一些被'NULL'性別?另外如果你嘗試'聯盟所有'?這會進一步提高第二個嗎?還有什麼RDBMS和執行計劃是什麼樣的?在SQL Server執行計劃中,相對成本也不一定反映真實的性能,如果這是您用來比較這兩個查詢。 –

回答

5

您的查詢2實際上是一個很好的竅門。它的工作原理是這樣的:你有一個性別索引。 DBMS可以兩次搜索該索引以獲得兩個範圍的行(一個用於M,一個用於F)。它不需要從這些行中讀取任何內容,只要它們存在即可。它可以計算兩個範圍中存在的行數。

在第一個查詢中,DBMS需要解碼行以讀取性別,然後它需要對行進行排序或構建一個散列表來對其進行聚合。這比僅計算行更昂貴。

+0

關於性別指數可以用於在第一查詢流聚集了。不需要排序,因爲它們已經處於索引順序。 –

+0

是的,但這些行需要解碼並相互比較。 – usr

+0

該行需要在一個索引查找過,知道要被解碼時,它已經到達最後一行匹配尋求謂語,應停止掃描。 –

0

查詢的優化取決於數據庫。你所看到的是數據庫特定的。

如書面所述,聯合會天真地需要兩次通過數據,做一個過濾器和一個計數。基本上不需要其他存儲。

聚合可能會對數據進行排序然後進行計數。或者,它可能會生成一個哈希表。鑑於性能的差異,我猜想正在使用排序。顯然,這對於這種類型的查詢來說是過分的。

如果您有關於性別的指標,這兩種方法將基本上掃描索引所以性能應該是相似的(工會版本可能掃描兩次=

是否正在使用提供了一種數據庫如果是這樣,你應該更新統計數據,看看你是否仍然得到相同的結果。

另外,你可以發佈「解釋」的結果或執行計劃嗎?這正好可以解釋爲什麼一個是比其他更快

2

Are you sure? 也許第二個q uery只是從第一個使用緩存的資源。

分別在兩個批次中運行它們並在每次運行之前運行DBCC FREEPROCCACHE以清理緩存。然後比較每個執行計劃的值。

+1

這也是我的猜測 – Filip

0

我試過一個等價的查詢,但發現相反的結果;工會佔了65%,而「小組靠」佔了35%。 (使用SQL Server 2008)。我沒有性別索引,因此我的執行計劃顯示聚集索引掃描。除非詳細檢查執行計劃,否則不可能解釋這個結果。

爲這個查詢添加一個索引可能不是一個好主意,因爲你可能不會像將要在客戶表中插入記錄一樣頻繁地運行此查詢。在其他一些帶位圖索引(Oracle,PostgreSQL)的數據庫引擎中,數據庫引擎可以組合多個索引,這樣就可以改變單列索引的效用。但在SQL Server中,您需要設計索引以「覆蓋」常用查詢。

相關問題