1. 程式人生 > >with as 和group by 代替 count distinct,提高效能

with as 和group by 代替 count distinct,提高效能

資料庫:postgresql

背景:使用distinct在對某張表某個欄位做去重統計的時候,發現有統計特別慢(30-40s),當前表大小是400w,distinct 後大概60w

sql 很簡單(出於安全考慮,欄位和表名稱都做了替換): 原sql: select count(distinct(name)) d from test.a 優化後sql: with c as ( select count(1) from test.a group by name ) select count(1) from c; 檢視兩者的執行計劃 執行計劃1: test=> EXPLAIN ANALYZE  select count(distinct(name)) d from test.a;
                                                             QUERY PLAN                                                             ------------------------------------------------------------------------------------------------------------------------------------  Aggregate  (cost=141971.71..141971.72 rows=1 width=14) (actual time=29829.643..29829.644 rows=1 loops=1)    ->  Seq Scan on a
 (cost=0.00..129323.37 rows=5059337 width=14) (actual time=0.007..772.693 rows=5371860 loops=1)  Total runtime: 29829.683 ms (3 rows) 執行計劃2:  explain ANALYZE  with c as ( select count(1) fromtest.a group by name ) select count(1) from c;                                                                  QUERY PLAN                                                                   ---------------------------------------------------------------------------------------------------------------------------------------------  Aggregate  (cost=161422.68..161422.70 rows=1 width=0) (actual time=4296.913..4296.913 rows=1 loops=1)    CTE c      ->  HashAggregate  (cost=154618.10..156711.82 rows=209372 width=14) (actual time=3636.989..3981.577 rows=777972 loops=1)            ->  Seq Scan on a
 (cost=0.00..129321.73 rows=5059273 width=14) (actual time=0.031..1097.439 rows=5371718 loops=1)    ->  CTE Scan on c  (cost=0.00..4187.44 rows=209372 width=0) (actual time=3636.994..4241.660 rows=777972 loops=1)  Total runtime: 4319.893 ms (6 rows) 可以看到,對於兩個sql而言都需要進行全表掃描,不同點在於,掃描後的聚合方式。 對於group by 而言 使用的是 HashAggregate,通過一個hash表來進行去重(但是不能出現hash衝突,記憶體消耗大),但是速度快。可以理解成 o(n) 對於 distinct 來說,聚合資料的時候,是通過對資料進行排序來去重的,效能最快也就是 nlogn 參考:

相關推薦

with as group by 代替 count distinct提高效能

資料庫:postgresql 背景:使用distinct在對某張表某個欄位做去重統計的時候,發現有統計特別慢(30-40s),當前表大小是400w,distinct 後大概60w sql 很簡單(出於安全考慮,欄位和表名稱都做了替換): 原sql: select count

Sql distinctgroup by的區別

distinct和Group by 區別:  distinct只是將重複的行從結果中出去;  group by是按指定的列分組,一般這時在select中會用到聚合函式。  distinct是把不同的記錄顯示出來。 

tp5 去重查詢 distinctgroup by

例子 $teachers_list=Db::name('class') ->alias('c') ->join('admin a','c.teachers_id = a.id') ->join('teachers t','a

distinctgroup by 去掉重複資料分析

詳見:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp40 用distinct關鍵字只能過濾查詢欄位中所有記錄相同的(記錄集相同),而如果要指定一個欄位卻沒有效果,另外distinct關鍵字會排序 。 s

oracle中distinctgroup by的區別

其實二者沒有什麼可比性,但是對於不包含聚集函式的GROUP BY操作來說,和DISTINCT操作是等價的。不過雖然二者的結果是一樣的,但是二者的執行計劃並不相同。 在Oracle9i中: SQL> SELECT * FROM V$VERSION; BANNER -------

mysql GROUP BY 代替DISTINCT 遇到的問題及解決

近日在做一個數據分析時,發現DISTINCT比較慢,想通過group by來替代。然而替代並非一帆風順,在替代過程中,發現對於重複資料,group by會取第一次出現的記錄。為得到我想要的統計資料,折騰了一番。下面用例項來描述我的問題及調整過程。 場景:有一張表,記錄手機使

關於distinct group by的去重邏輯淺析

在資料庫操作中,我們常常遇到需要將資料去重計數的工作。例如: 表A,列col A C A B C D A B 結果就是一共出現4個不同的字母A、B、C、D 即結果為4 大體上我們可以選擇count(distinct col)的方法和group+c

ThinkPHP去重 distinctgroup by

近期專案中,遇到資料表去重要求,對於ThinkPHP的去重有了更加準確的認識和體會。 兩種去重方式: $test_data = M('hot'); //例項化資料表 $data = $test_d

ThinkPHP去重 distinctgroup by總結

近期專案中,遇到資料表去重要求,對於ThinkPHP的去重有了更加準確的認識和體會。 兩種去重方式://例項化資料表 $test_data = M('hot'); //利用distinct方法去重 $data = $test_data->Distinct(true)

Hive中distinctGroup by效率對比及處理方式

select res.flag AS flag ,res.source AS source ,res.template AS template ,SUM(res.click_user)

mysql聯合查詢是用DISTINCTGROUP BY之間的效能區別

在開發過程中遇到的問題: 有兩張表,登入記錄表和IP歸屬表 需求:查詢某個地區和某個時間段登入的記錄 有登入表有4000條資料,IP歸屬表有400條資料 用GROUP BY查詢結果 SELECT * FROM login_log WHERE acctLoginIP IN

distinctgroup by區別

distinct簡單來說就是用來去重的,而group by的設計目的則是用來聚合統計的,兩者在能夠實現的功能上有些相同之處,但應該仔細區分,因為用錯場景的話,效率相差可以倍計。 單純的去重操作使用distinct,速度是快於group by的。 distinct di

Hive SQL 的 DISTINCT GROUP BY效能對比

    Hive SQL 的 DISTINCT 和 GROUP BY 都可用於資料去重,此文不講解 DISTINCT 和 GROUP BY 的基本用法,重點分析 DISTINCT 和 GROUP BY 用於資料去重時的效

distinctgroup by的效率

加了索引之後 distinct 比沒加索引的 distinct 快。 加了索引之後 group by 比沒加索引的 group by 快。 再來對比 :distinct  和 group by 不管是加不加索引 group by 都比 distinct 快。因此使用的時候建

GROUP BY ORDER BY一起使用時要註意的問題!

聚合 pan csdn under line order 註意 net asp 轉:http://blog.csdn.net/haiross/article/details/38897835 註意:ORDER BY 子句中的列必須包含在聚合函數或 GROUP BY 子句中。

partition bygroup by對比

今天大概弄懂了partition by和group by的區別聯絡。 1. group by是分組函式,partition by是分析函式(然後像sum()等是聚合函式); 2. 在執行順序上, 以下是常用sql關鍵字的優先順序 from > where > group by >

Oracle之with asupdate用法

許久不用,又忘了,做個記錄 update test b set b.code=(with t as(select t.id,code||'_'||row_number() over(partition by code order by id) codefrom test t)select a.code fr

mysql聯查中使用ifgroup by會讓你的結果不是你想要的

mysql中的if語句遇到統計count group by的時候會出現不準確的情況,原因是分組後if條件的結果以第一條為準,不會跟著分組   例如: SELECT SQL_NO_CACHE t1.*,t2.nick_name,t2.avatar,IF(t1.user_id=104080,

linq中order by group by (含lambda表示式實現)以及綜合案例

一、Linq對誰適用 linq的語法通過System.Linq下面的Enumerable類提供支援,也就是說,只要是實現了IEnumerable<T>的物件都可以使用Linq的語法來查詢。LINQ定義了大約40個查詢操作符,如select、from、in、where、group by 以及ord

SQL UnionSQL Union All兩者用法區別效率以及與order by group by配合問題

SQL UNION 操作符 UNION 操作符用於合併兩個或多個 SELECT 語句的結果集。 請注意,UNION 內部的 SELECT 語句必須擁有相同數量的列。列也必須擁有相似的資料型別。同時,每條 SELECT 語句中的列的順序必須相同。 SQL UNION