亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

【摘要】

日常生活中,我們會(huì)遇到各種各樣的數(shù)據(jù),小到公司通訊錄,大到互聯(lián)網(wǎng)用戶行為分析。在進(jìn)行數(shù)據(jù)分析處理的過程中,查詢是必不可少的環(huán)節(jié),如何更加高效地進(jìn)行數(shù)據(jù)查詢。點(diǎn)擊:性能優(yōu)化技巧 - 查詢,來乾學(xué)院一探究竟!

SPL為用戶提供了強(qiáng)大的索引機(jī)制以及針對(duì)不同場(chǎng)景中各對(duì)象的查詢函數(shù),善加運(yùn)用,可以顯著提高查詢性能。

1 鍵值查找

1.1 序表

我們先建立一個(gè)份“通話記錄”的模擬數(shù)據(jù),通過這份數(shù)據(jù),來比較一下不同查詢函數(shù)對(duì)序表查詢性能的影響。建立模擬數(shù)據(jù)的代碼如下:

性能優(yōu)化技巧 - 查找

 

代碼1.1.1

其中部分?jǐn)?shù)據(jù)如下:

性能優(yōu)化技巧 - 查找

 

圖1.1.1

對(duì)序表進(jìn)行查詢,通常我們會(huì)想到使用A.select()函數(shù)。我們來看一下使用該函數(shù)的效果:

性能優(yōu)化技巧 - 查找

 

代碼1.1.2

查詢耗時(shí)為80毫秒。

對(duì)序表的鍵值進(jìn)行查詢時(shí),可以利用A.find()函數(shù)進(jìn)行查詢。示例代碼如下:

性能優(yōu)化技巧 - 查找

 

代碼1.1.3

查詢耗時(shí)為1毫秒。

這是因?yàn)樵诩闫鞯男虮碇校梢灾付硞€(gè)或某些字段作為主鍵,基于主鍵的查找可以使用專門的函數(shù)。比如代碼1.1.3中A5的find函數(shù),不僅能簡(jiǎn)化書寫,更能有效地提高計(jì)算性能。

當(dāng)鍵值較多時(shí),我們使用函數(shù)A.find@k ()進(jìn)行批量鍵值查找。示例代碼如下:

性能優(yōu)化技巧 - 查找

 

代碼1.1.4

要注意的是,在使用A.find()函數(shù)時(shí),需事先建立主鍵,否則會(huì)報(bào)“缺少主鍵”的錯(cuò)誤。

利用主鍵值查找的函數(shù),可以有效地提升計(jì)算性能,是由于在序表中為主鍵建立索引表。在代碼1.1.4中,未建立索引時(shí),平均查詢時(shí)間在1400毫秒左右;建立索引后,查詢平均耗時(shí)不到1毫秒。

序表中的數(shù)據(jù)量越大,需要查找的次數(shù)越多,對(duì)效率的提升就越明顯。

當(dāng)查詢條件對(duì)應(yīng)多個(gè)鍵時(shí),示例代碼如下:

性能優(yōu)化技巧 - 查找

 

代碼1.1.5

switch/join函數(shù)同樣需要根據(jù)主鍵值在序表中查找記錄,使用時(shí)會(huì)對(duì)維表自動(dòng)建立索引。若在多線程fork函數(shù)之前沒有對(duì)相應(yīng)維表建立索引,就會(huì)在每個(gè)線程中都自動(dòng)為該維表建立一個(gè)索引,執(zhí)行過程中會(huì)消耗更多內(nèi)存,這樣有可能會(huì)造成內(nèi)存溢出,如圖1.1.1.2,要注意避免,較好的處理方式可以參考圖 1.1.3。

性能優(yōu)化技巧 - 查找

 

圖 1.1.2 fork中的每個(gè)線程都自動(dòng)建立了索引導(dǎo)致內(nèi)存溢出

性能優(yōu)化技巧 - 查找

 

圖 1.1.3 fork執(zhí)行前,先對(duì)維表建立索引

1.2 集文件

對(duì)有序的集文件進(jìn)行查找,可以使用f.iselect()函數(shù)實(shí)現(xiàn)二分查找,該函數(shù)也支持批量查找,下面是個(gè)基于集文件使用f.iselect()批量查找的例子:

性能優(yōu)化技巧 - 查找

 

代碼1.2.1

代碼1.2.1,建立集文件[email protected]。顯然,Subscriber是有序的。

性能優(yōu)化技巧 - 查找

 

代碼1.2.2

代碼1.2.2,因?yàn)閒.iselect()是個(gè)二分查找函數(shù),所以需要注意代碼中的A2作為查詢序列,與集文件的編號(hào)一樣,都需要有序。還要注意,這里的選項(xiàng)@b不是二分法的意思,而是讀取通過f.export()函數(shù)導(dǎo)出的集文件。該集文件導(dǎo)出時(shí),注意需要使用選項(xiàng)@z,否則在使用f.iselect ()對(duì)集文件進(jìn)行查詢時(shí)會(huì)報(bào)錯(cuò)。

假設(shè)數(shù)據(jù)總量為N,使用二分法進(jìn)行查找的時(shí)間復(fù)雜度為logN(以 2 為底),當(dāng)數(shù)據(jù)量越大,性能提升也就越明顯。

1.3 組表

組表也有類似序表的T.find()和T.find@k()函數(shù),可以高效地實(shí)現(xiàn)鍵值查找。適合于在大維表中找出少量記錄的場(chǎng)景。我們來看這樣一個(gè)例子:

性能優(yōu)化技巧 - 查找

 

代碼1.3.1

代碼1.3.1,建立組表文件voiceBill.ctx,其中Subscriber是該組表的維。

性能優(yōu)化技巧 - 查找

 

代碼1.3.2

代碼1.3.2,對(duì)組表使用cs.select()函數(shù)進(jìn)行查詢,耗時(shí)為:13855毫秒。

性能優(yōu)化技巧 - 查找

 

代碼1.3.3

代碼1.3.3,對(duì)組表使用T.find()函數(shù)進(jìn)行查詢,耗時(shí)為:77毫秒。

對(duì)比可見:對(duì)于有維的組表,可以使用類似序表的T.find()函數(shù),進(jìn)行單個(gè)或者批量鍵值的查詢,其查詢效率遠(yuǎn)高于從篩選后的游標(biāo)中取數(shù)。

2 索引查找

組表上可以建立三種索引,每種索引針對(duì)的情況也不同,分別為:

1、 hash索引,適合單值查找,比如枚舉類型;

2、 排序索引,適合區(qū)間查找,比如數(shù)字、日期、時(shí)間類型;

3、 全文索引,用于模糊查詢,比如字符串類型。

下面我們來建立一個(gè)組表,使其數(shù)據(jù)類型覆蓋以上三種索引,如下:

性能優(yōu)化技巧 - 查找

 

代碼2.1

代碼2.1建立的組表,前十條記錄如下:

性能優(yōu)化技巧 - 查找

 

圖2.1

性能優(yōu)化技巧 - 查找

 

代碼2.2

代碼2.2,根據(jù)每列數(shù)據(jù)類型的特點(diǎn),建立不同類型的索引。建立好的索引和組表文件如圖2.2:

性能優(yōu)化技巧 - 查找

 

圖2.2

集算器能自動(dòng)識(shí)別條件找到合適的索引,等值和區(qū)間都可以,like(“A*”)式的也支持。我們來看下效果:

等值查找

性能優(yōu)化技巧 - 查找

 

代碼2.3

性能優(yōu)化技巧 - 查找

 

代碼2.4

代碼2.3是沒有省略索引名稱的寫法,代碼2.4是省略索引名稱的寫法。兩者時(shí)間消耗基本相同,都是100毫秒左右。

性能優(yōu)化技巧 - 查找

 

代碼2.5

代碼2.5使用普通游標(biāo)查詢同樣的記錄,查詢耗時(shí)則需要40秒左右。

區(qū)間查找

性能優(yōu)化技巧 - 查找

 

代碼2.6

代碼2.6對(duì)Subscriber使用排序索引,進(jìn)行區(qū)間查找,查詢耗時(shí)是70毫秒左右。

性能優(yōu)化技巧 - 查找

 

代碼2.7

代碼2.7使用普通游標(biāo)查詢同樣條件的記錄,查詢耗時(shí)則需要40秒左右。

模糊查找

性能優(yōu)化技巧 - 查找

 

代碼2.8

代碼2.8對(duì)Company使用全文索引,進(jìn)行模糊查詢,查詢耗時(shí)是1500毫秒左右。

性能優(yōu)化技巧 - 查找

 

代碼2.9

代碼2.9使用普通游標(biāo)查詢同樣條件的記錄,查詢耗時(shí)則需要40秒左右。

當(dāng)數(shù)據(jù)規(guī)模更大時(shí),例如:

性能優(yōu)化技巧 - 查找

 

代碼2.10

代碼2.10,建造了10億條結(jié)構(gòu)如圖2.3的組表文件employee.ctx。

性能優(yōu)化技巧 - 查找

 

圖2.3

性能優(yōu)化技巧 - 查找

 

代碼2.11

代碼2.11中,對(duì)大部分列建立了索引。組表與索引的各個(gè)文件如圖2.4。

性能優(yōu)化技巧 - 查找

 

圖2.4

多等值條件項(xiàng)&&時(shí),可以分別為每個(gè)字段建立索引。集算器能夠快速在多個(gè)索引中用歸并算法計(jì)算交集。比如:

性能優(yōu)化技巧 - 查找

 

代碼2.12

代碼2.12,查詢條件均為等值查詢,A3查出記錄數(shù)為324條,耗時(shí)31883毫秒。

但區(qū)間條件時(shí)不能再用歸并計(jì)算交集,集算器將只對(duì)其中一個(gè)條件使用索引,另一個(gè)條件使用遍歷計(jì)算,效果就會(huì)差,比如:

性能優(yōu)化技巧 - 查找

 

代碼2.13

代碼2.13,查詢條件均為區(qū)間條件,A3查出記錄數(shù)為389條,耗時(shí)70283毫秒。

3 索引緩存

組表索引提供了兩級(jí)緩存機(jī)制,可以用index@2或者index@3預(yù)先把索引的索引讀入內(nèi)存,如果需要重復(fù)多次使用索引查找,則可以有效提高性能。

選項(xiàng)@2、@3的意思分別是將索引的第二、三級(jí)緩存先加載進(jìn)內(nèi)存。經(jīng)過索引緩存的預(yù)處理,第一遍查詢時(shí)間也能達(dá)到查詢數(shù)百次后才能達(dá)到的極限值。@2相比@3緩存的內(nèi)容少,效果相對(duì)差一點(diǎn),但內(nèi)存占用也更少。使用時(shí)需要程序員根據(jù)具體場(chǎng)景來權(quán)衡@2還是@3。

性能優(yōu)化技巧 - 查找

 

代碼3.1

代碼3.1,基于代碼2.10建造的組表文件,不使用索引緩存,查詢耗時(shí)為31883毫秒。

性能優(yōu)化技巧 - 查找

 

代碼3.2

代碼3.2使用第三級(jí)索引緩存,查詢耗時(shí)為5225毫秒。

這里使用的是列存組表,列存采用了數(shù)據(jù)分塊并壓縮的算法,對(duì)于遍歷運(yùn)算來講,訪問數(shù)據(jù)量會(huì)變小,也就會(huì)具有更好的性能。但對(duì)于基于索引隨機(jī)取數(shù)的場(chǎng)景,由于要有額外的解壓過程,而且每次取數(shù)都會(huì)針對(duì)整個(gè)分塊,運(yùn)算復(fù)雜度會(huì)高很多。因此,從原理上分析,這時(shí)候的性能應(yīng)當(dāng)會(huì)比行存要差。將組表轉(zhuǎn)為行存后,查詢耗時(shí)僅為1592毫秒。

索引緩存在并行時(shí)可以復(fù)用,如下:

性能優(yōu)化技巧 - 查找

 

代碼3.3

代碼3.3,并行時(shí),A5的每個(gè)線程中都可以使用A2、A3中建立的第三級(jí)索引緩存,最終查詢耗時(shí)為21376毫秒。

4 帶值索引

組表的行存和列存形式都支持索引,列存索引查找比行存性能差,返回結(jié)果集較少時(shí)差異不明顯,大量返回時(shí)會(huì)有明顯劣勢(shì),在設(shè)計(jì)存儲(chǔ)方案時(shí)要權(quán)衡。

性能優(yōu)化技巧 - 查找

 

代碼4.1

代碼4.1建立組表文件id_600m.ctx,結(jié)構(gòu)為(#id,data) ,包含6億條記錄,其中:

A1:包含 26 個(gè)英文字母和 10 個(gè)阿拉伯?dāng)?shù)字的字符串。

A2、A3:建立結(jié)構(gòu)為 (id,data) 的組表文件,使用列式存儲(chǔ)方式。

A4:循環(huán) 6000 次,循環(huán)體B4、B5,每次生成 10 萬條對(duì)應(yīng)結(jié)構(gòu)的記錄,并追加到組表文件。

執(zhí)行后,生成組表文件:id_600m.ctx

性能優(yōu)化技巧 - 查找

 

代碼4.2

代碼4.2為組表id列建立索引。

執(zhí)行后,生成組表的索引文件:id_600m.ctx__id_idx。

列存組表生成時(shí) create() 函數(shù)加上 @r 選項(xiàng),即可變?yōu)樯尚写娼M表,其余代碼無異,這里不再舉例,當(dāng)返回?cái)?shù)據(jù)量較大時(shí):

性能優(yōu)化技巧 - 查找

 

代碼4.3

代碼4.3中,列存查詢耗時(shí)和行存查詢耗時(shí),也就是A5和A9的值分別為205270和82800毫秒。

組表支持一種帶值索引,即把查找字段也寫入索引,這樣可以不再訪問原組表即返回結(jié)果。但存儲(chǔ)空間會(huì)占用較多。

基于代碼4.1的列存組表文件id_600m.ctx。

性能優(yōu)化技巧 - 查找

 

代碼4.4

代碼4.4為組表id列建立索引,在對(duì)組表建立索引時(shí),當(dāng) index 函數(shù)有數(shù)據(jù)列名參數(shù),如本例 A2 中的 data,就會(huì)在建索引時(shí)把數(shù)據(jù)列 data 復(fù)制進(jìn)索引。當(dāng)有多個(gè)數(shù)據(jù)列時(shí),可以寫為:index(id_idx;id;data1,data2,…)。

因?yàn)樵谒饕凶隽巳哂啵饕募沧匀粫?huì)較大,本文中測(cè)試的列存組表和索引冗余后的文件大小為:

性能優(yōu)化技巧 - 查找

 

當(dāng)數(shù)據(jù)復(fù)制進(jìn)索引后,實(shí)際上讀取時(shí)不再訪問原數(shù)據(jù)文件了。

從 6 億條數(shù)據(jù)總量中取 1 萬條批量隨機(jī)鍵值,完整的測(cè)試結(jié)果對(duì)比:

性能優(yōu)化技巧 - 查找

 

5 批量鍵值

組表索引能夠識(shí)別出contain式條件,支持批量等值查找。

性能優(yōu)化技巧 - 查找

 

代碼5.1

代碼5.1建立組表文件id_600m.ctx,結(jié)構(gòu)為(#id,data) ,包含6億條記錄,其中:

A1:包含 26 個(gè)英文字母和 10 個(gè)阿拉伯?dāng)?shù)字的字符串。

A2、A3:建立結(jié)構(gòu)為 (id,data) 的組表文件,@r 選項(xiàng)表示使用行式存儲(chǔ)方式。

A4:循環(huán) 6000 次,循環(huán)體B4、B5,每次生成 10 萬條對(duì)應(yīng)結(jié)構(gòu)的記錄,并追加到組表文件。

執(zhí)行后,生成組表文件:id_600m.ctx。

性能優(yōu)化技巧 - 查找

 

代碼5.2

代碼5.2為組表id列建立索引。

執(zhí)行后,生成組表的索引文件:id_600m.ctx__id_idx

性能優(yōu)化技巧 - 查找

 

代碼5.3

代碼5.3,在組表的 icursor()這個(gè)函數(shù)中,使用索引 id_idx,以條件 A2.contain(id) 來過濾組表。集算器會(huì)自動(dòng)識(shí)別出 A2.contain(id) 這個(gè)條件可以使用索引,并會(huì)自動(dòng)將 A2 的內(nèi)容排序后從前向后查找。

進(jìn)階使用

使用排序索引多線程查找時(shí),按鍵值排序分組后扔給多個(gè)線程去查詢,避免兩個(gè)線程中有交叉內(nèi)容。同時(shí),還可以設(shè)計(jì)成多個(gè)組表,把鍵值能平均分配到多個(gè)組表上并行查找。

所謂多線程并行,就是把數(shù)據(jù)分成 N 份,用 N 個(gè)線程查詢。但如果只是隨意地將數(shù)據(jù)分成 N 份,很可能無法真正地提高性能。因?yàn)閷⒁樵兊逆I值集是未知的,所以理論上也無法確保希望查找的數(shù)據(jù)能夠均勻分布在每一份組表文件中。比較好的處理方式是先觀察鍵值集的特征,從而盡可能地進(jìn)行數(shù)據(jù)的均勻拆分。

如果鍵值數(shù)據(jù)有比較明顯的業(yè)務(wù)特征,我們可以考慮按照實(shí)際業(yè)務(wù)場(chǎng)景使用日期、部門之類的字段來處理文件拆分。如:將屬于部門 A 的 1000 條記錄均分在 10 個(gè)文件中,每個(gè)文件就有 100 條記錄。在利用多線程查詢屬于部門 A 的記錄時(shí),每個(gè)線程就會(huì)從各自對(duì)應(yīng)的文件中取數(shù)相應(yīng)的這 100 條記錄了。

下面我們來看個(gè)實(shí)際的例子,已有數(shù)據(jù)文件multi_source.txt的結(jié)構(gòu)如下:

性能優(yōu)化技巧 - 查找

 

其中 type 和 id 兩個(gè)字段作為聯(lián)合主鍵確定一條記錄,其中部分?jǐn)?shù)據(jù)如下:

性能優(yōu)化技巧 - 查找

 


性能優(yōu)化技巧 - 查找

 

代碼5.4

代碼5.4詳解:

A1:type 的枚舉值組成的序列。在實(shí)際情況中,枚舉列表可能來自文件或者數(shù)據(jù)庫(kù)數(shù)據(jù)源。。

A2:給枚舉值序列中每個(gè) type 一個(gè) tid。為后續(xù)的數(shù)字化主鍵合并做準(zhǔn)備。

A3~A6:從 multi_source.txt 文件中獲取數(shù)據(jù),并按照 A2 中的對(duì)應(yīng)關(guān)系,把 type 列的枚舉串變成數(shù)字,然后將 type 和 id 進(jìn)行合并后,生成新的主鍵 nid。

A7:使用循環(huán)函數(shù),創(chuàng)建名為“鍵值名 _ 鍵值取 N 的余數(shù) _T.ctx”的組表文件,其結(jié)構(gòu)同為 (#nid,data)。

A8:用循環(huán)函數(shù)將游標(biāo)數(shù)據(jù)分別追加到 N 個(gè)原組表上。比如當(dāng) N=1 時(shí),拼出的 eval 函數(shù)參數(shù)為:channel(A4).select(nid%4==0).attach(A7(1).Append(~.cursor()))。意思是對(duì)游標(biāo) A4 創(chuàng)建管道,將管道中記錄按鍵值 nid 取 4 的余數(shù),將余數(shù)值等于 0 的記錄過濾出來。attach 是對(duì)當(dāng)前管道的附加運(yùn)算,表示取和當(dāng)前余數(shù)值對(duì)應(yīng)的原組表,將當(dāng)前管道中篩選過濾出的記錄,以游標(biāo)記錄的方式追加到 A7(1),即第 1 個(gè)組表。

A9:循環(huán)游標(biāo) A6,每次獲取 50 萬條記錄,直至 A6 游標(biāo)中的數(shù)據(jù)取完。

執(zhí)行后,產(chǎn)出 4(這時(shí)例子取 N=4)個(gè)獨(dú)立的組表文件:

性能優(yōu)化技巧 - 查找

 


性能優(yōu)化技巧 - 查找

 

代碼5.5

代碼5.5,創(chuàng)建索引過程詳解:

A1:列出滿足 nid*T.ctx 的文件名(這里 * 為通配符),這里 @p 選項(xiàng)代表需要返回帶有完整路徑信息的文件名。使用 fork 執(zhí)行多線程時(shí),需要注意環(huán)境中的并行限制數(shù)是否設(shè)置合理。這里用了 4 個(gè)線程,設(shè)計(jì)器中對(duì)應(yīng)的設(shè)置如下:

性能優(yōu)化技巧 - 查找

 

B1:每個(gè)線程為各個(gè)組表建立對(duì)應(yīng)的索引文件,最終結(jié)果如下:

性能優(yōu)化技巧 - 查找

 


性能優(yōu)化技巧 - 查找

 

代碼5.6

代碼5.6,查詢過程詳解:

A1:從 keys.txt 獲取查詢鍵值序列,因?yàn)橹挥幸涣薪Y(jié)果,使用 @i 選項(xiàng),將結(jié)果返回成序列:

性能優(yōu)化技巧 - 查找

 

A2:把 A1 的序列按 4 的余數(shù)進(jìn)行等值分組:

性能優(yōu)化技巧 - 查找

 

A3、B3~B5:用 fork 函數(shù),按等值分組后的鍵值對(duì)各個(gè)組表分別并行查詢。這里的 fork 后面分別寫了兩個(gè)參數(shù),第一個(gè)是循環(huán)函數(shù) N.(~-1),第二個(gè)是 A2。在接下來的 B3、B4 中分別使用 A3(2) 和 A3(1) 來獲取 fork 后面這兩個(gè)對(duì)應(yīng)順序的參數(shù),B4:對(duì)組表文件進(jìn)行根據(jù) B3 中的鍵值集進(jìn)行數(shù)據(jù)篩選,B5:返回游標(biāo)。由于 A3 中是多個(gè)線程返回的游標(biāo)序列,所以 A6 中需要使用 conjx 對(duì)多個(gè)游標(biāo)進(jìn)行縱向連接。

A6~A7:將多個(gè)線程返回的游標(biāo)進(jìn)行縱向連接后,導(dǎo)出游標(biāo)記錄至文本文件,前幾行內(nèi)容如下。

性能優(yōu)化技巧 - 查找

分享到:
標(biāo)簽:性能 優(yōu)化
用戶無頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定