内置的数据无法实现高性能
這里說的“內(nèi)”, 是指數(shù)據(jù)庫之內(nèi)。
當(dāng)數(shù)據(jù)量變大時,我們常常會感到數(shù)據(jù)庫的性能下降明顯,但是,無論怎樣優(yōu)化 SQL(存儲過程)都仍然與根據(jù)數(shù)據(jù)量和運(yùn)算復(fù)雜度計算出來的理論性能相差甚遠(yuǎn)。這主要由如下幾方面原因造成:
1. SQL 限制與優(yōu)化困難
我們已經(jīng)多次說過,由于關(guān)系代數(shù)和 SQL 語法的限制,有許多高效的算法無法實(shí)施,比如前面說過的遍歷復(fù)用技術(shù),以及去年談過的 JOIN 優(yōu)化方法。使用 SQL 實(shí)現(xiàn)這類運(yùn)算時,只能采用復(fù)雜度更高的方法,冗余的數(shù)據(jù)訪問量和計算量非常大,而且也很難利用多 CPU 進(jìn)行并行計算。
SQL 不提倡分步計算,經(jīng)常一條語句寫出幾百行、嵌套很多層。不分步的長語句很難利用某個子句的計算結(jié)果,常常帶來不必要的重復(fù)計算。而且過于復(fù)雜的也會給數(shù)據(jù)庫優(yōu)化引擎造成負(fù)擔(dān),優(yōu)化引擎不能很好地理解運(yùn)算邏輯而設(shè)計出最優(yōu)的執(zhí)行路徑。我們常常發(fā)現(xiàn)一條語句的幾個子部分執(zhí)行都很快,結(jié)果集也不大,但合起來寫到一句 SQL 中就會很慢。
2. 存儲過程性能差
對于復(fù)雜的多步驟計算,我們常常要編寫存儲過程才能實(shí)現(xiàn)。而和 SQL 相比,存儲過程的取數(shù)遍歷過程要慢得多。同一個表的數(shù)據(jù),使用存儲過程先 FETCH 出來再做聚合,要比直接用 SQL 聚合的性能慢出幾倍到十幾倍,本來這兩者的運(yùn)算性能應(yīng)當(dāng)是差不多的(計算復(fù)雜度與數(shù)據(jù)訪問量都一樣)。有些針對明細(xì)數(shù)據(jù)的復(fù)雜處理只能把數(shù)據(jù)一條條取出才能實(shí)現(xiàn)時,這個性能就沒辦法得到保證了。
在存儲過程中,為了利用前面計算出來的中間結(jié)果,只要涉及集合性數(shù)據(jù)一般都要使用臨時表。而建表寫數(shù)的動作也是非常慢的,數(shù)據(jù)庫有太多約束性要求,而且常常需要把臨時表落地到外存。
3. 直接外部計算不現(xiàn)實(shí)
如果我們不采用 SQL,而將數(shù)據(jù)讀出后在庫外計算,是否可以提高性能呢?
大多數(shù)情況仍然不可以。一方面原因是數(shù)據(jù)庫 IO 性能大都很差,從數(shù)據(jù)庫中取數(shù),要比從文件系統(tǒng)中讀數(shù)的性能差出一個數(shù)據(jù)量,經(jīng)常發(fā)生取數(shù)時間遠(yuǎn)遠(yuǎn)超過計算時間的現(xiàn)象。
而且,有些高效算法會要求有特殊的存儲格式,比如需要事先將數(shù)據(jù)排序存儲,從而可以采用分段定位查找或?qū)崿F(xiàn)有序歸并算法,而基于無序集合的 SQL 在理論上就無法支持,必須先排序才能保證取出數(shù)據(jù)的有序性,結(jié)果排序時間會超過計算本身。再比如行存或列存的選擇,一般數(shù)據(jù)庫只會采用一種(支持 OLTP 用行存且不壓縮,面向 OLAP 用列存并壓縮),但使用行存還是列存需要由計算目標(biāo)決定,在遍歷式計算采用列存較為合適,而使用索引定位查找時則更適合用行存。有時為了性能還可能把同一份數(shù)據(jù)存儲冗余的多份以面向不同用途,而在數(shù)據(jù)庫中很難有這么靈活的處理方式。
解決辦法,就是數(shù)據(jù)外置,具體說就是把數(shù)據(jù)搬出數(shù)據(jù)庫。使用合理的存儲方案再配以適用的算法,對于許多幾百上千行的存儲過程,經(jīng)過這樣的改造后,性能常常都有幾倍的增長。
當(dāng)然,這又會帶來新的問題。主要有三個方面:一是可管理性,在數(shù)據(jù)庫中有統(tǒng)一的數(shù)據(jù)視圖和約束性檢查,而外部文件系統(tǒng)則沒有這些東西;二是安全性,數(shù)據(jù)庫是個封閉體系,獲取數(shù)據(jù)的接口很單一,總有帳號認(rèn)證的過程,而文件系統(tǒng)也沒有這些東西;三是數(shù)據(jù)更新能力,數(shù)據(jù)在不斷地變化中,數(shù)據(jù)庫有完整的數(shù)據(jù)更新功能,文件系統(tǒng)這方面卻很弱,一般只能做追加,還很難保證追加過程中的一致性(中途出錯時恢復(fù))。
目前階段這個事還是需要權(quán)衡,獲得了數(shù)據(jù)庫的方便性就得不到高性能,要數(shù)據(jù)外置的高性能就要犧牲方便性。不過,隨著技術(shù)的進(jìn)步,在文件系統(tǒng)上加強(qiáng)可管理性、安全性以及可更新能力又不犧牲或很少犧牲其性能,還是有可能做到的,數(shù)據(jù)庫的封閉性總要被打破。
作者:279400248
鏈接:http://c.raqsoft.com.cn/article/1535513386417
來源:乾學(xué)院
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
總結(jié)
以上是生活随笔為你收集整理的内置的数据无法实现高性能的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在敏捷中应用测试驱动开发
- 下一篇: 这份程序员的简历刷爆了九月的朋友圈