當前位置:首頁 » 編程語言 » sqldistinct效率
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

sqldistinct效率

發布時間: 2023-02-28 06:58:48

A. mysql sql優化之 優化GROUP BY 和 DISTINCT

創建表tb_point 表

准備空的tb_box表

函數

編寫存儲過程,給tb_box表添加100萬條數據

修改關聯數據

好於

優於

在執行以下語句時會報錯:

前面在 https://www.jianshu.com/p/95e50fd017ea 文章中有提到這個問題,是直接修改sql_mode將 ONLY_FULL_GROUP_BY直接幹掉。但是在《高性能mysql》中有一段話是這樣的:

那麼既然指出不要直接修改 sql_mode,那麼我們應該如何讓沖突的GRUOPBY語句正確執行呢?

文中有提到,可以使用max()和min()函數來實現;但是這種方式使用max和min函數較真的人可能會說這樣寫的分組查詢有問題,確實如此。但是如果更加在乎查詢效率,這樣做也無可厚非。

如果,實在無法接受使用上面那種方式的話,可以這樣使用子查詢的方式來進行查詢:

書上對於這種方式有描述如下:
這樣寫更滿足關系理論,但是成本有點高,因為子查詢需要填充臨時表,而子查詢中創建的臨時表是沒有任何索引的。
作者認為這樣寫對性能有影響。

但是從我測得結果來看,子查詢的耗時反而更少。性能反而更佳。這個子查詢耗時0.4秒。而使用max方式耗時0.8秒。幾乎一倍。我的mysql版本是 5.7.22-log

為了解其中的原因,我們查看它的執行計劃:
可見,因為子查詢而產生了一層 DERIVED 臨時表,但是這個臨時表的Extra欄位有顯示 Using index、key裡面顯示自建索引。說明用到了索引。這是查詢性能可觀的一個重要原因吧;

另外我分別使用 SHOW PROFILE命令查看各部分耗時,對比之下。沒看到有哪部分耗時差別特別大,使用JOIN、MAX 耗時比上子查詢耗時都差不多是1倍

有些時候對一沒有建立索引的欄位,進行GRUOP BY時。會產生Using filesort 文件內排序。因為GRUOP BY是在排序的基礎上進行分組的。

如下面sql:

如果業務上不對排序有要求。那麼就可以禁止GRUOP BY的排序:

這樣就把Using filesort給幹掉了! 執行時間 1.237

當然,多數情況是多排序有要求的。此時也可以在GRUOP BY後面使用DESC和ASC關鍵字,使分組的結果集按需要的方向排序。如下:

分組查詢的一個變種就是要求mysql對分組結果再進行一次超級聚合。可以使用GROUP BY WITH ROLLUP 來實現這種邏輯,但可能性能不佳。因為通過查詢計劃分析出它是使用 Using temporary; Using filesort 來實現的。

使用WITH ROLLUP,查詢時間2.531秒。不使用0.774 秒。

1、所以,很多時候。我們在應用程序中做超級聚合是最好的!

2、當然也可使用UNION ALL 來實現:

3、還可以通過FROM子句嵌套使用子查詢:

B. SqlServer2005中 distinct關鍵字的使用

顯示重復記錄,還是有重復時只顯示一條

如:

--> --> (Roy)生成測試數據

if not object_id('Tempdb..#T') is null
drop table #T
Go
Create table #T([ID] int,[Name] nvarchar(1),[Memo] nvarchar(2))
Insert #T
select 1,N'A',N'A1' union all
select 2,N'A',N'A2' union all
select 3,N'A',N'A3' union all
select 4,N'B',N'B1' union all
select 5,N'B',N'B2'
Go

--I、Name相同ID最小的記錄(推薦用1,2,3),方法3在SQl05時,效率高於1、2
方法1:
Select * from #T a where not exists(select 1 from #T where Name=a.Name and ID<a.ID)

方法2:
select a.* from #T a join (select min(ID)ID,Name from #T group by Name) b on a.Name=b.Name and a.ID=b.ID

方法3:
select * from #T a where ID=(select min(ID) from #T where Name=a.Name)

方法4:
select a.* from #T a join #T b on a.Name=b.Name and a.ID>=b.ID group by a.ID,a.Name,a.Memo having count(1)=1

方法5:
select * from #T a group by ID,Name,Memo having ID=(select min(ID)from #T where Name=a.Name)

方法6:
select * from #T a where (select count(1) from #T where Name=a.Name and ID<a.ID)=0

方法7:
select * from #T a where ID=(select top 1 ID from #T where Name=a.name order by ID)

方法8:
select * from #T a where ID!>all(select ID from #T where Name=a.Name)

方法9(注:ID為唯一時可用):
select * from #T a where ID in(select min(ID) from #T group by Name)

--SQL2005:

方法10:
select ID,Name,Memo from (select *,min(ID)over(partition by Name) as MinID from #T a)T where ID=MinID

方法11:

select ID,Name,Memo from (select *,row_number()over(partition by Name order by ID) as MinID from #T a)T where MinID=1

生成結果:
/*
ID Name Memo
----------- ---- ----
1 A A1
4 B B1

C. sql中,只使用union和先union all再distinct,兩種方式哪個效率高

Distinct可以說是數據查詢中最耗時最耗性能的操作了,去重統計是數據查詢不可言說的痛,所以不到萬不得已不要用,另外,union all 後在distinct的效率如果更高的話,那union存在的意義是什麼?所以可想而知,union的效率更高啊

D. sqlserver 用distinct和group by哪個效率高

sql server資料庫進行查詢語句時,distinct和group by的效率比較,group by的效率更高一點,因為group by通過group進行排序而distinct是全表排序資源消耗更多。所以,group by效率更高。

E. SQL語句查詢 如何刪除重復多餘的數據

這個是SQL中distinct的典型用法:
1)從字面意思就可以了解到:
distinct
[dis'tiŋkt]
adj.
明顯的;獨特的;清楚的;有區別的
2)在SQL中用distinct來消除重復出現的
欄位
值。
使得每個欄位值只出現一次。
具體用法如下:
select
distinct
欄位名
from
表;
distinct
欄位名
意思就是只顯示一次該欄位名
一般情況下和order
by
結合使用,這樣可以提高效率。
所以這個問題的答案是:select
distinct
1,2,3,4
from
表;
1,2,3,4分別代表第一,二,三,四列的欄位名,我猜測可能第一列就是每個人的ID,
這樣你把重復的ID過濾留下一個,估計就是你想要的結果了。
希望我的回答能讓您滿意。

F. SQL中distinct的用法是什麼

在表中,可能會包含重復值。這並不成問題,不過,有時您也許希望僅僅列出不同(distinct)的值。關鍵詞 distinct用於返回唯一不同的值。

表A:

返回的結果為兩行,這說明distinct並非是對xing和ming兩列「字元串拼接」後再去重的,而是分別作用於了xing和ming列。

3.COUNT統計

select count(distinct name) from A; --表中name去重後的數目, SQL Server支持,而Access不支持

count是不能統計多個欄位的,下面的SQL在SQL Server和Access中都無法運行。

select count(distinct name, id) from A;

若想使用,請使用嵌套查詢,如下:

select count(*) from (select distinct xing, name from B) AS M;

4.distinct必須放在開頭

select id, distinct name from A; --會提示錯誤,因為distinct必須放在開頭

5.其他

distinct語句中select顯示的欄位只能是distinct指定的欄位,其他欄位是不可能出現的。例如,假如表A有「備注」列,如果想獲取distinc name,以及對應的「備注」欄位,想直接通過distinct是不可能實現的。但可以通過其他方法實現關於SQL Server將一列的多行內容拼接成一行的問題討論

G. sql語句去重distinct方法是什麼

sql語句去重distinct方法是根據name和id兩個欄位來去重的。這種方式Access和SQLServer同時支持,返回的結果為兩行,這說明distinct並非是對xing和ming兩列字元串拼接後再去重的,而是分別作用於了xing和ming列。

sql語句去重distinct特點

distinct語句中select顯示的欄位只能是distinct指定的欄位,其他欄位是不可能出現的,例如假如表A有備注列,如果想獲取distincname,以及對應的備注欄位想直接通過distinct是不可能實現的,但可以通過其他方法實現關於SQLServer將一列的多行內容拼接成一行的問題討論。

distinct這個關鍵字用來過濾掉多餘的重復記錄只保留一條,但往往只用它來返回不重復記錄的條數,而不是用它來返回不重記錄的所有值。其原因是distinct只有用二重循環查詢來解決,而這樣對於一個數據量非常大的站來說,無疑是會直接影響到效率的。