主頁 > 資料庫 > 天天寫SQL,這些神奇的特性你知道嗎?

天天寫SQL,這些神奇的特性你知道嗎?

2022-09-15 08:18:45 資料庫

摘要:不要歪了,我這里說特性它不是 bug,而是故意設計的機制或語法,你有可能天天寫陳述句或許還沒發現原來還能這樣用,沒關系我們一起學下漲姿勢,

本文分享自華為云社區《【云駐共創】天天寫 SQL,你遇到了哪些神奇的特性?》,作者: 龍哥手記 ,

一 SQL 的第一個神奇特性

日常開發我們經常會對表進行聚合查詢操作,但只能在 SELECT 子句中寫下面 3 種內容:通過 GROUP BY 子句指定的聚合鍵、聚合函式(SUM 、AVG 等)、常量,不懂沒關系我們來看個例子

聽我解釋

有學生班級表(tbl_student_class) 以及資料如下

DROP TABLE IF EXISTS tbl_student_class;
CREATE TABLE tbl_student_class (
  id int(8) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
 sno varchar(12) NOT NULL COMMENT '學號',
 cno varchar(5) NOT NULL COMMENT '班級號',
 cname varchar(20) NOT NULL COMMENT '班級名',
 PRIMARY KEY (id)
) COMMENT='學生班級表';
-- ----------------------------
-- Records of tbl_student_class
-- ----------------------------
INSERT INTO tbl_student_class VALUES ('1', '20190607001', '0607', '影視7班');
INSERT INTO tbl_student_class VALUES ('2', '20190607002', '0607', '影視7班');
INSERT INTO tbl_student_class VALUES ('3', '20190608003', '0608', '影視8班');
INSERT INTO tbl_student_class VALUES ('4', '20190608004', '0608', '影視8班');
INSERT INTO tbl_student_class VALUES ('5', '20190609005', '0609', '影視9班');
INSERT INTO tbl_student_class VALUES ('6', '20190609006', '0609', '影視9班');

我想統計各個班(班級號、班級名)一個有多少人、以及最大的學號,我們該怎么寫這個查詢 SQL?我想大家用腳都寫得出來

SELECT cno,cname,count(sno),MAX(sno) 
FROM tbl_student_class
GROUP BY cno,cname;

可是有人會想了,cno 和 cname 本來就是一對一,cno 一旦確定,cname 也就確定了嗎,那 SQL 咱們是不是可以這么寫?

SELECT cno,cname,count(sno),MAX(sno) 
FROM tbl_student_class
GROUP BY cno;

執行報錯了

[Err] 1055 - Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'test.tbl_student_class.cname' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
提示資訊:SELECT 串列中的第二個運算式(cname)不在 GROUP BY 的子句中,同時它也不是**聚合函式**;這與 sql 模式:ONLY_FULL_GROUP_BY 不相容的哈

那為什么 GROUP BY 之后不能直接參考原表(不在 GROUP BY 子句)中的列 ?莫急,我們慢慢往下看就明白了

1.0 SQL 模式

MySQL 服務器可以在不同的 SQL 模式下運行,并且可以針對不同的客戶端以不同的方式應用這些模式,具體取決于 sql_mode 系統變數的值,DBA 可以設定全域 SQL 模式以匹配站點服務器操作要求,并且每個應用程式可以將其會話 SQL 模式設定為其自己的要求,

模式會影響 MySQL 支持的 SQL 語法以及它執行的資料驗證檢查,這使得在不同環境中使用 MySQL 以及將 MySQL 與其他資料庫服務器一起使用變得更加容易,更多詳情請查官網自己找:Server SQL Modes

MySQL 版本不同,內容會略有不同(包括默認值),查閱的時候注意與自身的 MySQL 版本保持一致哈

SQL 模式主要分兩類:語法支持類和資料檢查類,常用的如下

語法支持類

  • ONLY_FULL_GROUP_BY
    對于 GROUP BY 聚合操作,如果在 SELECT 中的列、HAVING 或者 ORDER BY 子句的列,沒有在 GROUP BY 中出現,那么這個 SQL 是不合法的
  • ANSI_QUOTES
    啟用 ANSI_QUOTES 后,不能用雙引號來參考字串,因為它被解釋為識別符,設定它以后,update t set f1="" …,會報 Unknown column ‘’ in field list 這樣的語法錯誤
  • PIPES_AS_CONCAT
    把 || 視為字串的連接運算子而非 或 運算子,這種和 Oracle 資料庫是一樣的哈,也和字串的拼接函式 CONCAT () 有點類似
  • NO_TABLE_OPTIONS
    使用 SHOW CREATE TABLE 時不會輸出 MySQL 特有的語法部分,如 ENGINE,這個在使用 mysqldump 跨 DB 種類遷移的時候需要考慮
  • NO_AUTO_CREATE_USER
    字面意思不自動創建用戶,在給 MySQL 用戶授權時,我們習慣用 GRANT … ON … TO dbuser,順道一起創建用戶,設定該選項后就與 oracle 操作類似,授權之前必須先建立好用戶

1.1 資料檢查類

  • NO_ZERO_DATE

認為日期‘0000-00-00’非法,與是否設定后面的嚴格模式有關系

1、如果設定了嚴格模式,則 NO_ZERO_DATE 自然滿足,但如果是 INSERT IGNORE 或 UPDATE IGNORE,’0000-00-00’依然允許且只顯示 warning;

2、如果在非嚴格模式下,設定了 NO_ZERO_DATE,效果與上面一樣,’0000-00-00’ 允許但顯示 warning;如果沒有設定 NO_ZERO_DATE,no warning,當做完全合法的值;

3、NO_ZERO_IN_DATE 情況與上面類似,不同的是控制日期和天,是否可為 0 ,即 2010-01-00 是否合法;

  • NO_ENGINE_SUBSTITUTION

使用 ALTER TABLE 或 CREATE TABLE 指定 ENGINE 時,需要的存盤引擎被禁用或未編譯,該如何處理,啟用 NO_ENGINE_SUBSTITUTION 時,那么直接拋出錯誤;不設定此值時,CREATE 用默認的存盤引擎替代,ATLER 不進行更改,并拋出一個 warning

  • STRICT_TRANS_TABLES

設定它,表示啟用嚴格模式,注意 STRICT_TRANS_TABLES 不是幾種策略的組合,單獨指 INSERT、UPDATE 出現少值或無效值該如何處理:

1、前面提到的把 ‘’ 傳給 int,嚴格模式下非法,若啟用非嚴格模式則變成 0,產生一個 warning;

2、Out Of Range,變成插入最大邊界值;

3、當要插入的新行中,不包含其定義中沒有顯式 DEFAULT 子句的非 NULL 列的值時,該列缺少值

1.2 默認模式

當我們沒有修改組態檔的情況下,MySQL 是有自己的默認模式的;版本不同,默認模式也不同

-- 查看 MySQL 版本
SELECT VERSION();
-- 查看 sql_mode
SELECT @@sql_mode;
 

我們可以看到,5.7.21 的默認模式包含

ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

而第一個:ONLY_FULL_GROUP_BY 就會約束:當我們進行聚合查詢的時候,SELECT 的列不能直接包含非 GROUP BY 子句中的列,那如果我們去掉該模式(從 “嚴格模式” 到 “寬松模式”)呢?

 

我們發現,上述報錯的 SQL

-- 寬松模式下 可以執行
SELECT cno,cname,count(sno),MAX(sno) 
FROM tbl_student_class
GROUP BY cno;

能正常執行了,但是一般情況下不推薦這樣配置,線上環境往往是 “嚴格模式”,而不是 “寬松模式”;雖然案例中,無論是 “嚴格模式”,還是 “寬松模式”,結果都是對的,那是因為 cno 與 cname 唯一對應的,如果 cno 與 cname 不是唯一對應,那么在 “寬松模式下” cname 的值是隨機的,這就會造成難以排查的問題,有興趣的可以去試下;

二 SQL 的第二個神奇特性

2.1 問題描述下

今天我想比較兩個資料集

表 A 一共 50,000,000 行,其中有一列叫「ID」,表 B 也有一列叫「ID」,我想查的是有 A 表里有多少 ID 在 B 表里面,資料庫用的是 snowflake,它是一種一種多租戶、事務性、安全、高度可擴展的彈性資料庫,或者叫它實施數倉也行,具備完整的 SQL 支持和 schema-less 資料模式,支持 ACID 的事務,也提供用于遍歷、展平和嵌套半結構化資料的內置函式和 SQL 擴展,并支持 JSON 和 Avro 等流行格式;

用 query:

with A as
(
 select distinct(id) as id from Table_A
),
B as 
(
 select distinct(id) as id from Table_B 
),
result as 
(
 select * from A where id in (select id from B)
)
select count(*) from result

回傳結果是 26,000,000

也就是說,A 應有 24,000,000 行不在 B 里面,對吧

可是我把第 11 行的 in 改成 not in 后,情況有點出乎我的意料

with A as
(
 select distinct(id) as id from Table_A
),
B as 
(
 select distinct(id) as id from Table_B 
),
result as 
(
 select * from A where id not in (select id from B)
)
select count(*) from result

回傳結果竟然是 0,而不是 24,000,000

于是我在 snowflake 論壇搜了下,發現 5 年前在這帖子下面有人回復到:

If you use NOT IN (subquery), it compares every returned value and in case of NULL on any side of comparison it stops immediately with non defined result if you use NOT IN (subquery), it compares every returned value and in case of NULL on any side of comparison it stops immediately with non defined result

就是說,當你用 not in,subquery(例如上面第 11 行的 select id from B)里如果有 Null, 那么它就會立刻停止,回傳未定義的結果,所以最后結果是 0;

該如何解決?很簡單

2.2 去掉 null 值

在第 7 行加了限定 where id is not null 后,結果正常了

with A as
(
 select distinct(id) as id from Table_A
),
B as 
(
 select distinct(id) as id from Table_B where id is not null
),
result as 
(
 select * from A where id not in (select id from B)
)
select count(*) from result

最侄訓傳結果為 24,000,000,這樣就對了啊

2.3 用 not exists 代替 not in

注意第 11 行,用了 not exists 代替 not in

with A as
(
 select distinct(id) as id from Table_A
),
B as 
(
 select distinct(id) as id from Table_B where id is not null
),
result as 
(
 select * from A where not exists (select * from B where A.id=B.id)
)
select count(*) from result

回傳結果也為 24,000,000

當然,這肯定不是 bug 哈,而是特性,不然不會這么多年都留著,是我懂得太少了,得惡補下 SQL 哭泣,

不過不知道這個特性設計當初目的是什么,如果 subquery 回傳了 undefined,你好歹給我報個錯啊,這個「特性」不僅僅在 snowflake 上面出現,看 StackOverflow 上討論,貌似 Oracle 也是有這個「特性」的哈

三 SQL 的第三個神奇特性

像 Web 服務這樣需要快速回應的應用場景中,SQL 的性能直接決定了系統是否可以使用;特別在一些中小型應用中,SQL 的性能更是決定服務能否快速回應的唯一標準

嚴格地優化查詢性能時,必須要了解所使用資料庫的功能特點,此外,查詢速度慢并不只是因為 SQL 陳述句本身,還有可能記憶體分配不佳、檔案結構不合理、刷臟頁等其他原因啊;

因此下面介紹些 SQL 神奇特性,但不能解決所有的性能問題,但是卻能處理很多因 SQL 寫法不合理而產生的性能問題

所以下面盡量介紹一些不依賴具體資料庫實作,使 SQL 執行速度更快、消耗記憶體更少的優化技巧,只需調整 SQL 陳述句就能實作的通用的優化 Tip

3.1 環境準備

下文所講的內容是從 SQL 層面展開的哈,而不是針對某種特性的資料庫,也就是說,下文的內容基本上適用于任何關系型資料庫都可以;

但是,關系型資料庫那么多,逐一來演示示例了,顯然不太現實;我們以常用的 MySQL 來進行就行啦

MySQL 版本: 5.7.30-log ,存盤引擎: InnoDB

準備兩張表: tbl_customer 和 tbl_recharge_record

3.2 使用高效的查詢

針對某一個查詢,有時候會有多種 SQL 實作,例如 IN、EXISTS、連接之間的互相轉換

從理論上來講,得到相同結果的不同 SQL 陳述句應該有相同的性能的哈,但遺憾的是,查詢優化器生成的執行計劃很大程度上要受到外部資料結構的影響

所以,要想優化查詢性能,必須知道如何寫 SQL 陳述句才能使優化器生成更高效的執行計劃

3.3 使用 EXISTS 代替 IN

關于 IN,相信大家都比較熟悉,使用方便,也容易理解;雖說 IN 使用方便,但它卻存在性能瓶頸

如果 IN 的引數是 1,2,3 這樣的數值串列,一般還不需要特別注意,但如果引數是子查詢,那么就需要注意了

在大多時候, [NOT]IN 和 [NOT]EXISTS 回傳的結果是相同的,但是兩者用于子查詢時,EXISTS 的速度會更快一些

假設我們要查詢有充值記錄的顧客資訊,SQL 該怎么寫?

相信大家第一時間想到的是 IN

IN 使用起來確實簡單,也非常好理解;我們來看下它的執行計劃

我們再來看看 EXISTS 的執行計劃:

可以看到的是,IN 的執行計劃中新產生了一張臨時表: <subquery2> ,這會導致效率變慢

所以通常來講,EXISTS 比 IN 更快的原因有兩個

  • 1、如果連接列(customer_id)上建立了索引,那么查詢 tbl_recharge_record 時可以通過索引查詢,而不是全表查詢
  • 2、使用 EXISTS,一旦查到一行資料滿足條件就會終止查詢,不用像使用 IN 時一樣進行掃描全表(NOT EXISTS 也一樣)

如果當 IN 的引數是子查詢時,資料庫首先會執行子查詢,然后將結果存盤在一張臨時表里(行內視圖),然后掃描整個視圖,很多情況下這種做法非常耗費資源

使用 EXISTS 的話,資料庫不會生成臨時表

但是從代碼的可讀性上來看,IN 要比 EXISTS 好,使用 IN 時的代碼看起來更加一目了然,易于理解

因此,如果確信使用 IN 也能快速獲取結果,就沒有必要非得改成 EXISTS 了

其實有很多資料庫也嘗試著改善了 IN 的性能

Oracle 資料庫中,如果我們在有索引的列上使用 IN, 也會先掃描索引

PostgreSQL 從版 本 7.4 起也改善了使用子查詢作為 IN 謂詞引數時的查詢速度

說不定在未來的某一天,無論在哪個關系型資料庫上,IN 都能具備與 EXISTS 一樣的性能

3.4 使用連接代替 IN

其實在平時作業當中,更多的是用連接代替 IN 來改善查詢性能,而非 EXISTS,不是說連接更好,而是 EXISTS 很難掌握

回到問題:查詢有充值記錄的顧客資訊,如果用連接來實作,SQL 改如何寫?

這種寫法能充分利用索引;而且,因為沒有了子查詢,所以資料庫也不會生成中間表;所以,查詢效率是不錯的

至于 JOIN 與 EXISTS 相比哪個性能更好,這不太好說;如果沒有索引,可能 EXISTS 會略勝一籌,有索引的話,兩者都差不多

3.5 避免排序

說到 SQL 的排序,我們第一時間想到的肯定是:ORDERBY,通過它,我們可以按指定的某些列來順序輸出結果

但是,除了 ORDERBY 顯示的排序,資料庫內部還有很多運算在暗中進行排序;會進行排序的代表性的運算有下面這些

如果只在記憶體中進行排序,那么還好;但是如果因記憶體不足而需要在硬碟上排序,那么性能就會急劇下降

所以,要盡量避免(或減少)無謂的排序,能夠大大提高查詢效率

靈活使用集合運算子的 ALL 可選項

SQL 中有 UNION 、 INTERSECT 、 EXCEPT 三個集合運算子,分表代表這集合運算的 并集、交集、差集

默認情況下,這些運算子會為了排除掉重復資料而進行排序

Using temporary 表示進行了排序或者分組,顯然這個 SQL 并沒有進行分組,而是進行了排序運算

所以如果我們不在乎結果中是否有重復資料,或者事先知道不會有重復資料,可以使用 UNIONALL 代替 UNION 試下,可以看到,執行計劃中沒有排序運算了

對于 INTERSECT 和 EXCEPT 也是一樣的,加上 ALL 可選項后就不會進行排序了

加上 ALL 可選項是一個非常有效的優化手段,但各個資料庫對它的實作情況卻是參差不齊,如下圖所示

注意:Oracle 使用 MINUS 代替 EXCEPT;MySQL 壓根就沒有實作 INTERSECT 和 EXCEPT 運算

3.6 使用 EXISTS 來代替 DISTINCT

為了排除重復資料, DISTINCT 也會進行排序

還記得用連接代替 IN 的案例嗎,如果不用 DISTINCT

SQL:SELECT tc.*FROM tbl_recharge_record trr LEFTJOIN tbl_customer tc on trr.customer_id = tc.id

那么查出來的結果會有很多重復記錄,所以我們必須改進 SQL

SELECTDISTINCT tc.*FROM tbl_recharge_record trr LEFTJOIN tbl_customer tc on trr.customer_id = tc.id

會發現執行計劃中有個 Using temporary,它表示用到了排序運算

我們使用 EXISTS 來進行優化

可以看到,已經規避了排序運算

3.7 在極值函式中使用索引

SQL 語言里有兩個極值函式:MAX 和 MIN,使用這兩個函式時都會進行排序

例如: SELECTMAX (recharge_amount) FROM tbl_recharge_record

會進行全表掃描,并會進行隱式的排序,找出單筆充值最大的金額

但是如果引數欄位上建有索引,則只需掃描索引,但不需要掃描整張表

例如:SELECTMAX (customer_id) FROM tbl_recharge_record;

會通過索引: idx_c_id 進行掃描,找出充值記錄中最大的顧客 ID

但是這種方法并不是去掉了排序這一程序,而是優化了排序前的查找速度,從而減弱排序對整體性能的影響

能寫在 WHERE 子句里的條件千萬不要寫在 HAVING 子句里

我們來看兩個 SQL 以及其執行結果

你就明白了

從結果上來看,兩條 SQ 一樣;但是從性能上來看,第二條陳述句寫法效率更高,原因有兩個:

1)減少排序的資料量

GROUP BY 子句聚合時會進行排序,如果事先通過 WHERE 子句篩選出一部分行,就能夠減輕排序的負擔了

2)有效利用索引

3.8 WHERE 子句的條件里可以使用索引

HAVING 子句是針對聚合后生成的視圖進行篩選的,但是很多時候聚合后的視圖都沒有繼承原表的索引結構

關于 HAVING,更多詳情可查看:神奇的 SQL 之 HAVING→ 容易被輕視的主角

在 GROUP BY 子句和 ORDER BY 子句中使用索引

一般來說,GROUP BY 子句和 ORDER BY 子句都會進行排序

如果 GROUP BY 和 ORDER BY 的列有索引,那么可以提高查詢效率

特別是在一些資料庫中,如果列上建立的是唯一索引,那么排序程序本身都會被省略掉

  • 使用索引

使用索引是最常用的 SQL 優化手段,這個大家都知道,怕就怕大家不知道:明明有索引,為什么查詢還是這么慢(為什么索引沒用上)

關于索引未用到的情況,可查看:神奇的 SQL 之擦肩而過 → 真的用到索引了嗎,本文就不做過多闡述了

總之就是:查詢盡量往索引上靠,規避索引未用上的情況

  • 減少臨時表

在 SQL 中,子查詢的結果會被看成一張新表(臨時表),這張新表與原始表一樣,可以通過 SQL 進行操作

但是,頻繁使用臨時表會帶來兩個問題

  • 1、臨時表相當于原表資料的一份備份,會耗費記憶體資源
  • 2、很多時候(特別是聚合時),臨時表沒有繼承原表的索引結構

因此,盡量減少臨時表的使用也是提升性能的一個重要方法

  • 靈活使用 HAVING 子句

對聚合結果指定篩選條件時,使用 HAVING 子句是基本原則

但是如果對 HAVING 不熟,我們往往找出替代它的方式來實作,就像這樣

然而,對聚合結果指定篩選條件時不需要專門生成中間表,像下面這樣使用 HAVING 子句就可以

HAVING 子句和聚合操作都是同時執行的,所以比起生成臨時表后再執行 WHERE 子句,效率會更高一些,而且代碼看起來也更簡潔

需要對多個欄位使用 IN 謂詞時,讓它們匯總到一處

SQL-92 中加入了行與行比較的功能,這樣一來,比較謂詞 = 、<、> 和 IN 謂詞的引數就不再只是標量值了,而應是值串列了

我們來看一個示例,多個欄位使用 IN 謂詞

這段代碼中用到了兩個子查詢,我們可以進行列匯總優化,把邏輯寫在一起

這樣一來,子查詢不用考慮關聯性,而且只執行一次就可以

還可以進一步簡化,在 IN 中寫多個欄位的組合

簡化后,不用擔心連接欄位時出現的型別轉換問題,也不會對欄位進行加工,因此可以使用索引

先進行連接再進行聚合

連接和聚合同時使用時,先進行連接操作可以避免產生中間表

合理地使用視圖

視圖是非常方便的工具,我們在日常作業中經常用到

但是,如果沒有經過深入思考就定義復雜的視圖,可能會帶來巨大的性能問題

特別是視圖的定義陳述句中包含以下運算的時候,SQL 會非常低效,執行速度也會變得非常慢

小結下

文中雖然列舉了幾個要點,但其實優化的核心思想只有一個,那就是找出性能瓶頸所在,然后解決它;

其實不只是資料庫和 SQL,計算機世界里容易成為性能瓶頸的也是對硬碟,也就是檔案系統的訪問(因此可以通過增加記憶體,或者使用訪問速度更快的硬碟等方法來提升性能)

不管是減少排序還是使用索引,亦或是避免臨時表的使用,其本質都是為了減少對硬碟的訪問!

四 高斯資料庫特性為啥優異

首先,能釋放 CPU 多核心的計算資源

眾所周知,軟體計算能力的提升一方面得益于 CPU 硬體能力的增強,另一方面也得益于軟體設計層面能夠充分利用 CPU 的計算資源,當前處理器普遍采用多核設計,GaussDB (for MySQL) 單個節點最多可以支持 64 核的 CPU,單執行緒查詢的方式至多能用滿一個核的 CPU 資源,性能提升程度有限,遠遠無法滿足企業大資料量查詢場景下對降低時延的要求,因此,復雜的查詢分析型計算程序必須考慮充分利用 CPU 的多核計算資源,讓多個核參與到并行計算任務中才能大幅度提升查詢計算的處理效率;

下圖是使用 CPU 多核資源并行計算一個表的 count () 程序的例子:表資料進行切塊后分發給多個核進行并行計算,** 每個核計算部分資料得到一個中間 count () 結果 **,并在最后階段將所有中間結果進行聚合得到最終結果

然后,是并行查詢

GaussDB (for MySQL) 支持并行執行的查詢方式,用于降低分析型查詢場景的處理時間,滿足企業級應用對查詢低時延的要求,如前面所述,并行查詢的基本實作原理是將查詢任務進行切分并分發到多個 CPU 核上進行計算,充分利用 CPU 的多核計算資源來縮短查詢時間,并行查詢的性能提升倍數,理論上與 CPU 的核數正相關,就是說并行度越高能夠使用的 CPU 核數就越多,性能提升的倍數也就越高;

下圖展示的是:在 GaussDB (for MySQL) 的 64U 實體上查詢 100G 資料量的 COUNT (*) 查詢耗時,不同的查詢并發度分別對應不同耗時,并發度越高對應的查詢耗時越短

它支持多種型別的并行查詢算子,以滿足客戶各種不同復雜查詢場景,當前最新版本(2021-9)已經支持的并行查詢場景包括:

  • 主鍵查詢、二級索引查詢
  • 主鍵掃描、索引掃描、范圍掃描、索引等值查詢,索引逆向查詢
  • 并行條件過濾(where/having)、投影計算
  • 并行多表 JOIN(包括 HashJoin、NestLoopJoin、SemiJoin 等)查詢
  • 并行聚合函式運算,包括 SUM/AVG/COUNT/BIT_AND/BIT_OR/BIT_XOR 等
  • 并行運算式運算,包括算術運算、邏輯運算、一般函式運算及混合運算等
  • 并行分組 group by、排序 order by、limit/offset、distinct 運算
  • 并行 UNION、子查詢、視圖查詢
  • 并行磁區表查詢
  • 并行查詢支持的資料型別包括:整型、字符型、時間型別、浮點型等等
  • 其他查詢

下圖是 GaussDB (for MySQL) 并行查詢針對 TPC-H 的 22 條查詢場景所做的性能測驗結果,測驗資料量為 100G,并發執行緒資料是 32,下圖展示了并行查詢相比傳統 MySQL 單執行緒查詢的性能提升情況:32 并行執行下,單表復雜查詢最高提升 26 倍性能,普遍提升 20 + 倍性能,多表 JOIN 復雜查詢最高提升近 27 倍性能,普遍提升 10 + 倍性能,子查詢性能也有較大提升;

總而言之

GaussDB (for MySQL) 并行查詢充分呼叫了 CPU 的多核計算資源,極大降低了分析型查詢場景的處理時間,大幅度提升了資料庫性能,可以很好的滿足客戶多種復雜查詢場景的低時延要求,

 

點擊關注,第一時間了解華為云新鮮技術~

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/508140.html

標籤:SQL Server

上一篇:動手測起來!搭載全自研資料庫內核,我們將性能提升了20%

下一篇:多版本并發控制 MVCC

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more