偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

SQL(及存儲過程)跑得太慢怎么辦?

數(shù)據(jù)庫 新聞
如果一個計算的實現(xiàn)過于復(fù)雜,其開發(fā)代價已經(jīng)遠(yuǎn)遠(yuǎn)超過性能優(yōu)化本身,那也就沒有優(yōu)化的意義了。

SQL 作為目前最常用的數(shù)據(jù)處理語言,廣泛應(yīng)用于查詢、跑批等場景。當(dāng)數(shù)據(jù)量較大時,使用 SQL(以及存儲過程)經(jīng)常會發(fā)生跑得很慢的情況,這就要去優(yōu)化 SQL。優(yōu)化 SQL 有一些特定的套路,通常先要查看執(zhí)行計劃來定位 SQL 慢的原因,然后針對性改寫來優(yōu)化 SQL,比如對于連續(xù)數(shù)值判斷可以用 between 來替代 in,select 語句指明字段名稱,用 union all 替代 union,把 exists 改寫成 join 等。當(dāng)然還有一些工程上的優(yōu)化手段,如建立索引,使用臨時表 / 匯總表等,優(yōu)化的方法有很多,相信各位 DBA 都不會陌生。

但遺憾的是,仍然有相當(dāng)多情況無論怎樣優(yōu)化都不可能跑得更快。這里 做 SQL 性能優(yōu)化真是讓人干瞪眼 介紹了一些,并做了相應(yīng)的技術(shù)分析。由于其理論基礎(chǔ)關(guān)系代數(shù)的局限,SQL 缺乏離散性和有序集合等特性的支持使得 SQL 在表達(dá)某些高性能算法時異常困難,甚至完全寫不出來,只能采用比較笨的低性能算法,眼睜睜地看著硬件資源被白白浪費。在 寫著簡單跑得又快的數(shù)據(jù)庫語言 SPL 中有對 SQL 理論基礎(chǔ)缺陷的通俗解釋。

也就是說,SQL 的慢是理論性的,這種問題僅僅由數(shù)據(jù)庫在工程層面優(yōu)化只能局部改善(確實有不少商業(yè)數(shù)據(jù)庫能夠自動識別某些 SQL 并轉(zhuǎn)換成高性能算法),而不能根本地解決問題(情況復(fù)雜時數(shù)據(jù)庫優(yōu)化引擎都會“暈”掉,只能按 SQL 的書寫邏輯執(zhí)行成低性能算法)。

理論性的缺陷當(dāng)然也不能寄希望于更換數(shù)據(jù)庫而得到解決,只要還是用 SQL,即使采用分布式數(shù)據(jù)庫、內(nèi)存數(shù)據(jù)庫也還是這種情況,在消耗更大成本的資源后當(dāng)然也能有一定的性能提升,但和硬件本應(yīng)能夠達(dá)到的性能仍然有巨大的差距。

那還能怎么辦?

那就不能再用 SQL!也就不能再用關(guān)系數(shù)據(jù)庫了。

那用什么?

SQL 描述不了這些高性能算法,用 Java,C++ 行嗎?

沒問題!從理論上講,Java、C++ 什么算法都能實現(xiàn),而且因為可以控制計算機(jī)底層的動作,這類代碼通??梢耘艹龊芎玫乃俣龋ㄖ灰绦騿T能力不是太差)。

不過,不要高興得太早,雖然都寫得出來,但由于這些開發(fā)語言過于原生,本身沒有提供什么面向數(shù)據(jù)處理的高性能計算類庫,想實現(xiàn)這些算法就必須從頭實現(xiàn),而這恐怕要累死。以哈希關(guān)聯(lián)為例,Java 實現(xiàn)至少要寫幾百行代碼,不僅要設(shè)計合適的哈希函數(shù),還要解決可能出現(xiàn)的哈希沖突,這一套下來的工程量可不??;還有在 Java 中進(jìn)行多線程編程也并非易事,但并行計算又是提升計算性能的有效手段。類似的,涉及結(jié)構(gòu)化數(shù)據(jù)計算的算法還有很多,這些都自己來做的復(fù)雜度可想而知。如果一個計算的實現(xiàn)過于復(fù)雜,其開發(fā)代價已經(jīng)遠(yuǎn)遠(yuǎn)超過性能優(yōu)化本身,那也就沒有優(yōu)化的意義了。

Python 也面臨類似的問題,雖然在結(jié)構(gòu)化數(shù)據(jù)計算類庫方面要比 Java 豐富得多,但并沒有提供必要的高性能算法庫和存儲方案,比如沒有提供為大數(shù)據(jù)服務(wù)的游標(biāo)類型及相關(guān)運算,也沒提供有效的并行機(jī)制。想要實施那些高性能算法也只能自己開發(fā),但 Python 作為解釋執(zhí)行語言,本身運行效率不高,在此基礎(chǔ)上再開發(fā)的算法也往往達(dá)不到高性能要求。同樣,Scala 也缺乏足夠的高性能計算類庫,自己編寫的算法同樣復(fù)雜度相當(dāng)高,對于不熟悉這些算法的程序員來講,從頭實現(xiàn)的代碼的運行效率往往還不如努力優(yōu)化后商用數(shù)據(jù)庫 SQL 的速度。

那就只能忍受 SQL 的慢了嗎?

還可以用 SPL!

SPL 和高性能

開源 SPL(Structured Process Language),一個專門面向結(jié)構(gòu)化數(shù)據(jù)處理的程序語言。使用 SPL 可以讓原本 SQL 跑得慢的計算變快。

為什么 SPL 能跑得快?是擁有了什么改變硬件性能的黑科技嗎?

那倒沒有。軟件改變不了硬件的計算性能,SPL 也一樣。簡單來說,SPL 快就是上面說的,要使用更高性能的算法。SPL 中提供了大量基礎(chǔ)的高性能算法類庫,基于這些算法庫實現(xiàn)的代碼可以有效減少計算量,而我們做計算就是組合運用這些算法,每種計算都快一些,那整體上就會快很多,從而達(dá)到提升計算性能的目的。

SPL 設(shè)計的這些高性能算法,像遍歷復(fù)用、有序歸并、外鍵預(yù)關(guān)聯(lián)、標(biāo)簽位維度、并行計算等,都已經(jīng)封裝好。這其中有很多算法都是 SPL 獨創(chuàng)的,在業(yè)內(nèi)也是首次出現(xiàn)。

圖片

基于這些封裝好的算法庫,再寫程序會就很方便,拿來直接用而不需要從頭自己開發(fā),不僅性能高,開發(fā)也快。從這個角度來看,跑得快和寫著簡單其實是一回事,就是能高效率地編寫高性能算法。反觀 Java、C++、Python、Scala 由于缺少這些算法庫,想要實現(xiàn)高性能也就很難了。

SPL 采用和 SQL 不同的觀念看待同一個計算任務(wù),繼而可以采用不同(更低)復(fù)雜度的計算方法。

在實戰(zhàn)中,SPL 目前已經(jīng)做過不少性能優(yōu)化案例,少則提速數(shù)倍,多則數(shù)十倍,極端情況還有提速上千倍的,提速一個數(shù)量級基本上是常態(tài)。

比如在優(yōu)化某保險公司車險保單跑批的案例( 開源 SPL 優(yōu)化保險公司跑批優(yōu)從 2 小時到 17 分鐘)中,使用 SPL 將計算時間從 2 小時縮短到 17 分鐘,同時代碼量減少了 2/3。這里使用了 SPL 特有的遍歷復(fù)用技術(shù),可以在對大數(shù)據(jù)的一次遍歷過程中實現(xiàn)多種運算,有效地減少外存訪問量。這個案例涉及對一個大表進(jìn)行三次關(guān)聯(lián)和匯總的運算,使用 SQL 要將大表遍歷三次,而使用 SPL 只需要遍歷一次,并在關(guān)聯(lián)運算上也采用了不同的方法,因此獲得了巨大的性能提升。

還有在 開源 SPL 將銀行手機(jī)賬戶查詢的預(yù)先關(guān)聯(lián)變成實時關(guān)聯(lián) 的案例中,使用 SPL 將原本只能預(yù)關(guān)聯(lián)的手機(jī)賬戶查詢變成實時關(guān)聯(lián),同時服務(wù)器數(shù)量從 6 臺降為 1 臺。這里充分利用了 SPL 的有序存儲機(jī)制,一次性讀取整個賬戶數(shù)據(jù)時可以有效減少硬盤時間(物理存儲連續(xù)),再借助區(qū)分維表和事實表的外鍵實時關(guān)聯(lián)技術(shù)使用單機(jī)就能完成實時關(guān)聯(lián)查詢,性能提升明顯,硬件需求也降低了許多。

進(jìn)一步討論

說到這里你可能會想,那是不是學(xué)會 SPL 語法就能把計算跑得快了?

也沒這么簡單!

關(guān)于算法

使用 SPL 可以獲得更高性能不是因為 SPL 語法,SPL 語法雖然有些特色,但并不是跑得快的根本原因。最關(guān)鍵的是掌握和運用高性能算法。

實現(xiàn)性能優(yōu)化有兩步:第一步設(shè)計出低復(fù)雜的計算方案,第二步用足夠低的成本實現(xiàn)它。其中更關(guān)鍵的是第一步,這需要由有一定經(jīng)驗和知識儲備的程序員來做(即掌握和運用高性能算法),第二步才是用 SPL 來做。換句話說,SPL 并不負(fù)責(zé)設(shè)計解決問題的方法,而只是負(fù)責(zé)讓解法更容易實現(xiàn)出來。

SPL 語法很簡單,比 Java 容易得多,兩小時就能基本上手,兩三周就能比較熟練了。但算法卻沒那么簡單,需要認(rèn)真學(xué)習(xí)反復(fù)練習(xí)才能掌握。反過來,只要掌握了算法,用什么語法就是個相對次要的問題了(當(dāng)然用 SQL 這種太粗線條的語言還是不行)。這就像給病人看病,找出病理原因后,能分析出什么成分的藥能管用。無論直接購買成藥(使用封裝過的 SPL),還是上山采藥(使用 Java/C++ 硬寫),都可以治好病,無非就是麻煩程度和支付成本不同。

因為實際中很少使用,有不少應(yīng)用程序員工作幾年后都把大學(xué)時代學(xué)過的數(shù)據(jù)結(jié)構(gòu)和算法課程內(nèi)容忘了,而不理解這些基礎(chǔ)算法知識時也就沒辦法設(shè)計出高性能算法方案。為此,SPL 設(shè)置了專門的高性能專題,不僅涵蓋高性能算法與優(yōu)化技巧,還有性能優(yōu)化課程與性能圖書來授人以漁。

高性能計算專題

http://c.raqsoft.com.cn/article/1647044897121

性能優(yōu)化圖書

http://c.raqsoft.com.cn/article/1613911172557

性能優(yōu)化課程

http://www.raqsoft.com.cn/wx/course-performance-optimizing.html

關(guān)于存儲

和算法密切相關(guān)的,高性能計算還有一個關(guān)鍵點是數(shù)據(jù)存儲,高性能計算離不開合理的數(shù)據(jù)存儲方式。使用 SPL 實施高性能計算時也不能再基于數(shù)據(jù)庫來做,需要將數(shù)據(jù)從數(shù)據(jù)庫里搬出來重新組織。

為什么呢?

慢的數(shù)據(jù)計算任務(wù)可以分為計算密集型和數(shù)據(jù)密集型兩大類。單純的計算密集型任務(wù)涉及的數(shù)據(jù)量不大而只是計算量很大,計算量大并不是由于數(shù)據(jù)量大造成的,這樣不用改變存儲方式,只要實施了好的計算方法也能大幅提升性能,也就是說,可以繼續(xù)在原有的存儲方式(比如數(shù)據(jù)庫)上使用 SPL 來優(yōu)化性能。而數(shù)據(jù)密集型任務(wù)涉及的計算量也很大,但計算量大主要是由數(shù)據(jù)量大造成的,這時候如果不改變存儲方式,數(shù)據(jù)讀取時間很可能會很長,即使能把計算時間優(yōu)化到 0,整體運算時間也不能得到有效的優(yōu)化。

遺憾的是,我們面臨的計算慢的場景絕大部分屬于數(shù)據(jù)密集型計算。如果數(shù)據(jù)還存在數(shù)據(jù)庫中,而數(shù)據(jù)庫取數(shù)接口(如 JDBC)通常又非常慢,將數(shù)據(jù)讀出就要消耗很長時間(IO 效率很低),經(jīng)常遠(yuǎn)遠(yuǎn)超過后續(xù) SPL 計算的時間,這也就不可能達(dá)到優(yōu)化效果了。而且,SPL 中有相當(dāng)多的算法也對存儲組織有要求,比如單邊分堆算法就要求有序的存儲方式,而常規(guī)關(guān)系數(shù)據(jù)庫無法滿足這個前提,這些算法也無法實施了。

為了解決這個問題,SPL 提供了自有的存儲機(jī)制,直接采用文件系統(tǒng),將數(shù)據(jù)從數(shù)據(jù)庫導(dǎo)出到特定格式的文件中,不僅可以獲得更高的 IO 存取效率以及文件系統(tǒng)靈活的管理能力,還可以充分利用自有格式的列存、有序、壓縮、并行分段等數(shù)據(jù)存儲優(yōu)勢,從而高效地發(fā)揮高性能算法效力。

使用文件存儲數(shù)據(jù)還可以有效減少數(shù)據(jù)入庫的時間,進(jìn)一步提升計算性能。有些計算場景不僅要從數(shù)據(jù)源讀,還要將計算結(jié)果落地,存入數(shù)據(jù)庫以方便后續(xù)計算使用。像 ETL 就是典型的讀寫并存的計算,還有某些大數(shù)據(jù)計算或復(fù)雜計算需要將中間結(jié)果暫存,后續(xù)計算還需要再使用的情況。我們知道,數(shù)據(jù)庫寫入是非常慢的動作,伴隨寫入的計算場景性能自然低下。這時就可以將原本需要入庫的數(shù)據(jù)存儲在文件中(雖然這是工程方面的優(yōu)勢,但仍可獲得接近數(shù)量級的讀寫性能提升),再利用 SPL 的文件計算能力直接計算,從而實現(xiàn)高性能。

關(guān)于 T+0

如果把數(shù)據(jù)都移到數(shù)據(jù)庫外,那么是不是就無法完成實時數(shù)據(jù)計算了?畢竟數(shù)據(jù)總是在不斷地產(chǎn)生。

沒有問題。

對于全量 T+0 實時查詢,SPL 提供了多源混合計算的能力以滿足這類場景。冷數(shù)據(jù)量大且不再變化使用 SPL 的高性能文件存儲,這樣可以獲得更高地計算性能;熱數(shù)據(jù)量小仍然存放在原有數(shù)據(jù)源中,SPL 直接讀取計算(支持多樣性數(shù)據(jù)源),由于熱數(shù)據(jù)量并不大,直接基于生產(chǎn)數(shù)據(jù)源查詢也不會對其造成太大影響,訪問時間也不會太長。冷熱數(shù)據(jù)混合計算,就可以獲得針對全量數(shù)據(jù)的 T+0 實時查詢。我們只要定期將變冷的數(shù)據(jù)固化到 SPL 的高性能存儲中,原數(shù)據(jù)源只需要保持少量近期新產(chǎn)生的熱數(shù)據(jù)即可。整體架構(gòu)如下:

圖片

如何開始

從前面的分析可以知道,完成性能優(yōu)化任務(wù)必須熟悉高性能算法和存儲機(jī)制,但從上面的課程圖書也可以看出來,這些內(nèi)容并不少,都要融會貫通也不是很容易的事。特別是很多程序員都習(xí)慣了 SQL 的思維方式,很難跳出這個窠臼。面對一個性能優(yōu)化任務(wù),即使有了開源 SPL 這樣的有利武器,也常常有點無從下手。打個比方,一個趕馬車的高手想跑得更快時,會習(xí)慣于尋找韁繩和鞭子,而對于初次見到的汽車上的方向盤和油門卻會感到一頭霧水。

為此,SPL 團(tuán)隊也提供相應(yīng)的咨詢服務(wù):你可以把遇到的性能問題拿過來與我們一起討論和設(shè)計優(yōu)化方案,必要的時候還可以進(jìn)行 POC。

我們通常關(guān)心這樣一些必要的問題信息:業(yè)務(wù)場景、面臨痛點、當(dāng)前計算的數(shù)據(jù)量和并發(fā)量以及響應(yīng)時間,如果還能提供 SQL 腳本、表結(jié)構(gòu)和測試數(shù)據(jù)就更好了。

相信我們,從不失手!

經(jīng)歷過一兩個案子,程序員們就會熟悉 SPL 的思維方式(理解了方向盤和油門),以后再自己做性能優(yōu)化就不是問題了。

天下武功,唯快不破,但只有掌握了快的本質(zhì)和方法才能所向無敵。你說是不是?

責(zé)任編輯:張燕妮 來源: 悟空料架構(gòu)
相關(guān)推薦

2022-12-20 08:46:41

MySQL主從復(fù)制

2023-09-02 20:13:01

代碼網(wǎng)速

2022-08-26 16:28:41

MySQL存儲只讀語句

2017-12-04 08:37:31

存儲空間NAS

2010-09-01 16:35:12

SQL刪除存儲過程

2022-02-15 07:36:21

SQLEXPLAIN數(shù)據(jù)庫

2009-11-03 08:56:02

linux死機(jī)操作系統(tǒng)

2024-04-22 08:17:23

MySQL誤刪數(shù)據(jù)

2022-12-19 11:31:57

緩存失效數(shù)據(jù)庫

2017-02-21 13:11:43

SDN網(wǎng)絡(luò)體系SDN架構(gòu)

2022-05-19 08:01:49

PostgreSQL數(shù)據(jù)庫

2019-10-12 09:50:46

Redis內(nèi)存數(shù)據(jù)庫

2018-01-28 20:39:39

戴爾

2022-07-05 11:48:47

MySQL死鎖表鎖

2015-10-22 09:09:59

BAT投資VC

2010-07-15 12:38:14

SQL Server存

2021-04-28 16:58:41

QQ解凍QQ移動應(yīng)用

2009-08-06 16:44:06

2010-10-29 16:22:37

SQL存儲過程

2020-04-08 20:10:47

MySQLETL數(shù)據(jù)庫
點贊
收藏

51CTO技術(shù)棧公眾號