Ị nwere ike ịgụ gbasara ihe isi KDB+, asụsụ mmemme Q bụ, ihe ike na adịghị ike ha dị na mbụ m. na nkenke na mmalite. N'isiokwu a, anyị ga-emejuputa ọrụ na Q nke ga-edozi iyi data na-abata ma gbakọọ ọrụ nchịkọta dị iche iche kwa nkeji na ọnọdụ "ezigbo oge" (ya bụ, ọ ga-enwe oge iji gbakọọ ihe niile tupu akụkụ ọzọ nke data). Isi ihe dị na Q bụ na ọ bụ asụsụ vector nke na-enye gị ohere iji ọ bụghị otu ihe rụọ ọrụ, kama ọ na-eji usoro ha, usoro nhazi na ihe ndị ọzọ dị mgbagwoju anya. Asụsụ ndị dị ka Q na ndị ikwu ya K, J, APL bụ ndị ama ama maka mkpirisi ha. Ọtụtụ mgbe, mmemme nke na-ewe ọtụtụ enyo nke koodu n'asụsụ a ma ama dị ka Java nwere ike dee na ha n'ahịrị ole na ole. Nke a bụ ihe m chọrọ igosi n'isiokwu a.

Okwu Mmalite
KDB+ bụ nchekwa data kọlụm lekwasịrị anya na nnukwu data, nyere iwu n'otu ụzọ (karịsịa site na oge). A na-eji ya eme ihe na ụlọ ọrụ ego - ụlọ akụ, ego ntinye ego, ụlọ ọrụ mkpuchi. Asụsụ Q bụ asụsụ ime KDB+ na-enye gị ohere iji data a rụọ ọrụ nke ọma. Echiche Q bụ nkenke na arụmọrụ, ebe a na-achụ ihe doro anya. Nke a ziri ezi site n'eziokwu na asụsụ vector ga-esi ike ịghọta n'ọnọdụ ọ bụla, na mkpụmkpụ na ụbara nke ndekọ ahụ na-enye gị ohere ịhụ akụkụ ka ukwuu nke mmemme ahụ n'otu ihuenyo, nke n'ikpeazụ na-eme ka ọ dịkwuo mfe nghọta.
N'ime edemede a anyị na-emejuputa mmemme zuru oke na Q ma ị nwere ike ịnwale ya. Iji mee nke a, ị ga-achọ Q. Ị nwere ike ibudata ụdị 32-bit n'efu na webụsaịtị ụlọ ọrụ kx - . N'ebe ahụ, ọ bụrụ na ị nwere mmasị, ị ga-ahụ ozi ntinye aka na Q, akwụkwọ ahụ na akụkọ dị iche iche gbasara isiokwu a.
Ulationkpụzi nsogbu a
Enwere isi iyi na-eziga tebụl nwere data kwa milliseconds 25 ọ bụla. Ebe ọ bụ na a na-eji KDB + eme ihe n'ụzọ bụ isi na ego, anyị ga-eche na nke a bụ tebụl azụmahịa (ahia), nke nwere ogidi ndị a: oge (oge na milliseconds), sym (nhazi ụlọ ọrụ na mgbanwe ngwaahịa - IBM, AAPL,…), ọnụ ahịa (ọnụahịa nke e ji zụta mbak), nha (nha azụmahịa). Ogologo oge nke millisekọnd 25 bụ aka ike, ọ bụghị oke obere na ọ bụghịkwa ogologo oge. Ọnụnọ ya pụtara na data ahụ na-abịa na ọrụ echekwabara. Ọ ga-adị mfe iji mejuputa buffering n'akụkụ ọrụ, gụnyere nchikota ike dabere na ibu dị ugbu a, mana maka ịdị mfe, anyị ga-elekwasị anya na etiti oge.
Ọrụ ahụ ga-agụrịrị nkeji ọ bụla maka akara ngosi ọ bụla na-abata site na kọlụm sym otu ọrụ nchịkọta ọnụ - ọnụ ahịa kacha elu, ọnụ ahịa nkezi, nha nchikota, wdg. ozi bara uru. Maka ịdị mfe, anyị ga-eche na enwere ike ịgbakọ ọrụ niile n'ụzọ dị ukwuu, ya bụ. iji nweta uru ọhụrụ, ọ ga-ezuru ịmara ọnụọgụ abụọ - ochie na ụkpụrụ na-abata. Dịka ọmụmaatụ, ọrụ kachasị, nkezi, nchikota nwere ihe onwunwe a, mana ọrụ etiti adịghị.
Anyị ga-echekwa na iyi data na-abata bụ oge akwadoro. Nke a ga-enye anyị ohere ịrụ ọrụ naanị na nkeji ikpeazụ. Na omume, ọ ga-ezuru iji nwee ike ịrụ ọrụ na nkeji ugbu a na nke gara aga ma ọ bụrụ na mmelite ụfọdụ abịaghị n'oge. Maka mfe, anyị agaghị atụle ikpe a.
Ọrụ nchịkọta
Edepụtara ọrụ nchịkọta achọrọ n'okpuru. Ewere m ọtụtụ n'ime ha ka enwere ike ịbawanye ibu na ọrụ ahụ:
- elu - ọnụ ahịa kachasị - ọnụahịa kacha elu kwa nkeji.
- ọnụ ala - nkeji - ọnụahịa kacha nta kwa nkeji.
- FirstPrice – mbụ price – mbụ price kwa nkeji.
- lastPrice – ikpeazụ price – ikpeazụ price kwa nkeji.
- nke mbụ - nha mbụ - nha azụmaahịa mbụ kwa nkeji.
- Ogo ikpeazụ - nha ikpeazụ - nha azụmaahịa ikpeazụ n'ime nkeji.
- numTrades – gụọ i – ọnụọgụ azụmaahịa kwa nkeji.
- olu - nchikota nha - nchikota nha ahia kwa nkeji.
- pvolume - ọnụ ahịa nchikota - nchikota ọnụ ahịa kwa nkeji, achọrọ maka avgPrice.
- - nchikota ọnụahịa ntụgharị * nha - mkpokọta mkpokọta azụmahịa kwa nkeji.
- avgPrice – pvolume%numTrades – nkezi ọnụahịa kwa nkeji.
- avgSize – olu%numTrades – nkezi ahia nha kwa nkeji.
- vwap - ntụgharị% olu - nkezi ọnụahịa kwa nkeji jiri nha azụmahịa tụọ ya.
- cumVolume – nchikota olu – chịkọbara nha azụmahịa n'ime oge niile.
Ka anyị tụlee otu isi ihe na-edoghị anya ozugbo - otu esi amalite kọlụm ndị a na nke mbụ yana maka nkeji ọ bụla na-esote. Ụfọdụ kọlụm nke ụdị ọnụahịa mbụ ga-eburịrị ka ọ ghara imebi oge ọ bụla akọwapụtaghị uru ha bara. Ụdị olu ndị ọzọ ga-adịrịrị mgbe niile ka ọ bụrụ 0. E nwekwara ogidi ndị chọrọ ijikọ ụzọ - dịka ọmụmaatụ, a ga-edepụta cumVolume site na nkeji gara aga, na nke mbụ ka ọ bụrụ 0. Ka anyị jiri data ọkọwa okwu dozie ihe ndị a niile. ụdị (dị ka ndekọ):
// list ! list – создать словарь, 0n – float null, 0N – long null, `sym – тип символ, `sym1`sym2 – список символов
initWith:`sym`time`high`low`firstPrice`lastPrice`firstSize`lastSize`numTrades`volume`pvolume`turnover`avgPrice`avgSize`vwap`cumVolume!(`;00:00;0n;0n;0n;0n;0N;0N;0;0;0.0;0.0;0n;0n;0n;0);
aggCols:reverse key[initWith] except `sym`time; // список всех вычисляемых колонок, reverse объяснен ниже
M gbakwunyere sym na oge na akwụkwọ ọkọwa okwu maka ịdị mma, ugbu a initWith bụ ahịrị akwadoro site na tebụl chịkọbara ikpeazụ, ebe ọ ka dị ka ịtọọ sym na oge ziri ezi. Ị nwere ike iji ya tinye ahịrị ọhụrụ na tebụl.
Anyị ga-achọ aggCols mgbe ị na-eke ọrụ mkpokọta. A ga-atụgharịrịrị ndepụta ahụ n'ihi usoro a na-enyocha okwu na Q (site n'aka nri gaa n'aka ekpe). Ebumnuche bụ iji hụ na ngụkọ na-aga site na elu ruo na cumVolume, ebe ọ bụ na ogidi ụfọdụ na-adabere na ndị gara aga.
Ogidi ndị kwesịrị ka e depụtaghachi ya na nkeji ọhụrụ site na nke gara aga, a na-agbakwunye kọlụm sym maka ịdị mma:
rollColumns:`sym`cumVolume;
Ugbu a, ka anyị kewaa ogidi ndị ahụ n'ime otu dịka otu esi emelite ha. Enwere ike ịmata ụdị atọ:
- Accumulators (olu, ntụgharị, ..) - anyị ga-agbakwunye uru na-abata na nke gara aga.
- Na isi ihe pụrụ iche (elu, ala, ..) - uru mbụ na nkeji na-ewepụta site na data na-abata, ndị ọzọ na-agbakọ site na iji ọrụ ahụ.
- Zuo ike. A na-agbakọ oge niile site na iji ọrụ.
Ka anyị kọwapụta mgbanwe maka klaasị ndị a:
accumulatorCols:`numTrades`volume`pvolume`turnover;
specialCols:`high`low`firstPrice`firstSize;
Usoro ịgbakọ
Anyị ga-emelite tebụl chịkọtara na nkebi abụọ. Maka ịrụ ọrụ nke ọma, anyị na-ebu ụzọ belata tebụl na-abata ka ọ bụrụ naanị otu ahịrị maka agwa na nkeji ọ bụla. Eziokwu ahụ bụ na ọrụ anyị niile na-abawanye ma na-akpakọrịta na-ekwe nkwa na nsonaazụ nke usoro mgbakwunye a agaghị agbanwe. Ị nwere ike mebie tebụl site na iji họrọ:
select high:max price, low:min price … by sym,time.minute from table
Usoro a nwere ihe ọghọm - a na-akọwapụta usoro nke kọlụm gbakọọ. Ọ dabara nke ọma, na Q, a na-emejuputakwa nhọrọ dị ka ọrụ ebe ị nwere ike dochie arụmụka agbakwunyere ike:
?[table;whereClause;byClause;selectClause]
Agaghị m akọwa n'ụzọ zuru ezu usoro nke arụmụka n'ọnọdụ anyị, naanị site na họrọ okwu ga-abụ ihe na-adịghị mkpa na ha kwesịrị ịbụ akwụkwọ ọkọwa okwu nke ụdị ogidi! Ya mere, a pụrụ ịkọwa ọrụ mbelata dị ka ndị a:
selExpression:`high`low`firstPrice`lastPrice`firstSize`lastSize`numTrades`volume`pvolume`turnover!parse each ("max price";"min price";"first price";"last price";"first size";"last size";"count i";"sum size";"sum price";"sum price*size"); // each это функция map в Q для одного списка
preprocess:?[;();`sym`time!`sym`time.minute;selExpression];
Maka idoanya, ejiri m ọrụ parse, nke na-atụgharị eriri nwere okwu Q n'ime uru nke nwere ike ịfefe na ọrụ eval na nke achọrọ na ọrụ họrọ. Rịba ama na a kọwapụtara usoro nhazi dị ka ntule (ntụgharị, ọrụ nwere arụmụka akụkụ akụkụ) nke ọrụ họrọ, otu arụmụka (tebụl) na-efu. Ọ bụrụ na anyị etinye preprocess na tebụl, anyị ga-enweta tebụl abịakọrọ.
Nkeji nke abụọ bụ imelite tebụl chịkọtara. Ka anyị buru ụzọ dee algọridim na pseudocode:
for each sym in inputTable
idx: row index in agg table for sym+currentTime;
aggTable[idx;`high]: aggTable[idx;`high] | inputTable[sym;`high];
aggTable[idx;`volume]: aggTable[idx;`volume] + inputTable[sym;`volume];
…
Na Q, a na-ejikarị maapụ/belata ọrụ kama iji loops. Mana ebe Q bụ asụsụ vector na anyị nwere ike itinye ọrụ niile n'ụzọ dị mfe na akara niile n'otu oge, mgbe ahụ na mkpokọta mbụ anyị nwere ike ime na-enweghị loop ma ọlị, na-arụ ọrụ na akara niile ozugbo:
idx:calcIdx inputTable;
row:aggTable idx;
aggTable[idx;`high]: row[`high] | inputTable`high;
aggTable[idx;`volume]: row[`volume] + inputTable`volume;
…
Mana anyị nwere ike ịga n'ihu, Q nwere onye ọrụ pụrụ iche na nke siri ike - onye na-ahụ maka ọrụ n'ozuzu ya. Ọ na-enye gị ohere ịgbanwe otu ụkpụrụ na usoro data mgbagwoju anya site na iji ndepụta indices, ọrụ na arụmụka. N'ọnọdụ anyị, ọ dị ka nke a:
idx:calcIdx inputTable;
rows:aggTable idx;
// .[target;(idx0;idx1;..);function;argument] ~ target[idx 0;idx 1;…]: function[target[idx 0;idx 1;…];argument], в нашем случае функция – это присваивание
.[aggTable;(idx;aggCols);:;flip (row[`high] | inputTable`high;row[`volume] + inputTable`volume;…)];
O di nwute, iji kenye na tebụl ị chọrọ ndepụta ahịrị, ọ bụghị kọlụm, ma ị ga-atụgharị matriks (ndepụta nke kọlụm na ndepụta ahịrị) site na iji ọrụ ntụgharị. Nke a dị oké ọnụ maka tebụl buru ibu, ya mere, kama anyị na-etinye ọrụ n'ozuzu ya na kọlụm ọ bụla iche iche, na-eji ọrụ map (nke dị ka apostrophe):
.[aggTable;;:;]'[(idx;)each aggCols; (row[`high] | inputTable`high;row[`volume] + inputTable`volume;…)];
Anyị na-ejikwa amụma ọrụ ọzọ. Rịba ama na na Q, ịmepụta ndepụta bụkwa ọrụ na anyị nwere ike ịkpọ ya site na iji ọrụ ọ bụla (map) iji nweta ndepụta ndepụta.
Iji hụ na edoghị ntọala nke kọlụm gbakọọ, anyị ga-emepụta okwu ahụ dị n'elu n'ike. Ka anyị buru ụzọ kọwapụta ọrụ iji gbakọọ kọlụm ọ bụla, na-eji ahịrị na mgbanwe inp iji rụtụ aka na data chịkọtara na ntinye:
aggExpression:`high`low`firstPrice`lastPrice`firstSize`lastSize`avgPrice`avgSize`vwap`cumVolume!
("row[`high]|inp`high";"row[`low]&inp`low";"row`firstPrice";"inp`lastPrice";"row`firstSize";"inp`lastSize";"pvolume%numTrades";"volume%numTrades";"turnover%volume";"row[`cumVolume]+inp`volume");
Ụfọdụ ogidi ndị pụrụ iche; Anyị nwere ike ikpebi na ọ bụ nke mbụ site na kọlụm [`numTrades] - ọ bụrụ na ọ nwere 0, mgbe ahụ uru bụ nke mbụ. Q nwere ọrụ họrọ -?[Boolean list; list1; list2] - nke na-ahọrọ uru site na listi 1 ma ọ bụ 2 dabere na ọnọdụ dị na arụmụka mbụ:
// high -> ?[isFirst;inp`high;row[`high]|inp`high]
// @ - тоже обобщенное присваивание для случая когда индекс неглубокий
@[`aggExpression;specialCols;{[x;y]"?[isFirst;inp`",y,";",x,"]"};string specialCols];
N'ebe a, akpọrọ m ọrụ n'ozuzu ya na ọrụ m (okwu dị n'ihe nkwado gbagọrọ agbagọ). Ọ na-enweta uru dị ugbu a (arụmụka mbụ) na mgbagha ọzọ, nke m na-agafe na paramita 4th.
Ka anyị tinye igwe okwu batrị iche iche, ebe ọrụ ahụ bụ otu maka ha:
// volume -> row[`volume]+inp`volume
aggExpression[accumulatorCols]:{"row[`",x,"]+inp`",x } each string accumulatorCols;
Nke a bụ ọrụ nkịtị site na ụkpụrụ Q, mana m na-ekenye ndepụta ụkpụrụ ozugbo. N'ikpeazụ, ka anyị mepụta isi ọrụ:
// ":",/:aggExprs ~ map[{":",x};aggExpr] => ":row[`high]|inp`high" присвоим вычисленное значение переменной, потому что некоторые колонки зависят от уже вычисленных значений
// string[cols],'exprs ~ map[,;string[cols];exprs] => "high:row[`high]|inp`high" завершим создание присваивания. ,’ расшифровывается как map[concat]
// ";" sv exprs – String from Vector (sv), соединяет список строк вставляя “;” посредине
updateAgg:value "{[aggTable;idx;inp] row:aggTable idx; isFirst_0=row`numTrades; .[aggTable;;:;]'[(idx;)each aggCols;(",(";"sv string[aggCols],'":",/:aggExpression aggCols),")]}";
Site na okwu a, m na-emepụta ike na-arụ ọrụ site na eriri nwere okwu m nyere n'elu. Nsonaazụ ga-adị ka nke a:
{[aggTable;idx;inp] rows:aggTable idx; isFirst_0=row`numTrades; .[aggTable;;:;]'[(idx;)each aggCols ;(cumVolume:row[`cumVolume]+inp`cumVolume;… ; high:?[isFirst;inp`high;row[`high]|inp`high])]}
Atụgharịrị usoro nlele kọlụm n'ihi na n'ime Q usoro nyocha si n'aka nri gaa n'aka ekpe.
Ugbu a, anyị nwere isi ọrụ abụọ dị mkpa maka mgbako, naanị anyị kwesịrị ịgbakwunye obere akụrụngwa na ọrụ ahụ dị njikere.
Nzọụkwụ ikpeazụ
Anyị nwere preprocess na melite ọrụ Agg na-arụ ọrụ niile. Ma ọ ka dị mkpa iji hụ na ntụgharị ziri ezi site na nkeji ma gbakọọ index maka nchịkọta. Nke mbụ, ka anyị kọwapụta ọrụ init:
init:{
tradeAgg:: 0#enlist[initWith]; // создаем пустую типизированную таблицу, enlist превращает словарь в таблицу, а 0# означает взять 0 элементов из нее
currTime::00:00; // начнем с 0, :: означает, что присваивание в глобальную переменную
currSyms::`u#`symbol$(); // `u# - превращает список в дерево, для ускорения поиска элементов
offset::0; // индекс в tradeAgg, где начинается текущая минута
rollCache:: `sym xkey update `u#sym from rollColumns#tradeAgg; // кэш для последних значений roll колонок, таблица с ключом sym
}
Anyị ga-akọwakwa ọrụ mpịakọta, nke ga-agbanwe nkeji dị ugbu a:
roll:{[tm]
if[currTime>tm; :init[]]; // если перевалили за полночь, то просто вызовем init
rollCache,::offset _ rollColumns#tradeAgg; // обновим кэш – взять roll колонки из aggTable, обрезать, вставить в rollCache
offset::count tradeAgg;
currSyms::`u#`$();
}
Anyị ga-achọ ọrụ iji tinye mkpụrụedemede ọhụrụ:
addSyms:{[syms]
currSyms,::syms; // добавим в список известных
// добавим в таблицу sym, time и rollColumns воспользовавшись обобщенным присваиванием.
// Функция ^ подставляет значения по умолчанию для roll колонок, если символа нет в кэше. value flip table возвращает список колонок в таблице.
`tradeAgg upsert @[count[syms]#enlist initWith;`sym`time,cols rc;:;(syms;currTime), (initWith cols rc)^value flip rc:rollCache ([] sym: syms)];
}
Na n'ikpeazụ, ọrụ nkwalite (aha ọdịnala maka ọrụ a maka ọrụ Q), nke onye ahịa na-akpọ ịgbakwunye data:
upd:{[tblName;data] // tblName нам не нужно, но обычно сервис обрабатывает несколько таблиц
tm:exec distinct time from data:() xkey preprocess data; // preprocess & calc time
updMinute[data] each tm; // добавим данные для каждой минуты
};
updMinute:{[data;tm]
if[tm<>currTime; roll tm; currTime::tm]; // поменяем минуту, если необходимо
data:select from data where time=tm; // фильтрация
if[count msyms:syms where not (syms:data`sym)in currSyms; addSyms msyms]; // новые символы
updateAgg[`tradeAgg;offset+currSyms?syms;data]; // обновим агрегированную таблицу. Функция ? ищет индекс элементов списка справа в списке слева.
};
Ọ gwụla. Nke a bụ koodu ọrụ anyị zuru oke, dịka e kwere nkwa, naanị ahịrị ole na ole:
initWith:`sym`time`high`low`firstPrice`lastPrice`firstSize`lastSize`numTrades`volume`pvolume`turnover`avgPrice`avgSize`vwap`cumVolume!(`;00:00;0n;0n;0n;0n;0N;0N;0;0;0.0;0.0;0n;0n;0n;0);
aggCols:reverse key[initWith] except `sym`time;
rollColumns:`sym`cumVolume;
accumulatorCols:`numTrades`volume`pvolume`turnover;
specialCols:`high`low`firstPrice`firstSize;
selExpression:`high`low`firstPrice`lastPrice`firstSize`lastSize`numTrades`volume`pvolume`turnover!parse each ("max price";"min price";"first price";"last price";"first size";"last size";"count i";"sum size";"sum price";"sum price*size");
preprocess:?[;();`sym`time!`sym`time.minute;selExpression];
aggExpression:`high`low`firstPrice`lastPrice`firstSize`lastSize`avgPrice`avgSize`vwap`cumVolume!("row[`high]|inp`high";"row[`low]&inp`low";"row`firstPrice";"inp`lastPrice";"row`firstSize";"inp`lastSize";"pvolume%numTrades";"volume%numTrades";"turnover%volume";"row[`cumVolume]+inp`volume");
@[`aggExpression;specialCols;{"?[isFirst;inp`",y,";",x,"]"};string specialCols];
aggExpression[accumulatorCols]:{"row[`",x,"]+inp`",x } each string accumulatorCols;
updateAgg:value "{[aggTable;idx;inp] row:aggTable idx; isFirst_0=row`numTrades; .[aggTable;;:;]'[(idx;)each aggCols;(",(";"sv string[aggCols],'":",/:aggExpression aggCols),")]}"; / '
init:{
tradeAgg::0#enlist[initWith];
currTime::00:00;
currSyms::`u#`symbol$();
offset::0;
rollCache:: `sym xkey update `u#sym from rollColumns#tradeAgg;
};
roll:{[tm]
if[currTime>tm; :init[]];
rollCache,::offset _ rollColumns#tradeAgg;
offset::count tradeAgg;
currSyms::`u#`$();
};
addSyms:{[syms]
currSyms,::syms;
`tradeAgg upsert @[count[syms]#enlist initWith;`sym`time,cols rc;:;(syms;currTime),(initWith cols rc)^value flip rc:rollCache ([] sym: syms)];
};
upd:{[tblName;data] updMinute[data] each exec distinct time from data:() xkey preprocess data};
updMinute:{[data;tm]
if[tm<>currTime; roll tm; currTime::tm];
data:select from data where time=tm;
if[count msyms:syms where not (syms:data`sym)in currSyms; addSyms msyms];
updateAgg[`tradeAgg;offset+currSyms?syms;data];
};
Ule
Ka anyị lelee arụmọrụ nke ọrụ ahụ. Iji mee nke a, ka anyị mee ya na usoro dị iche (tinye koodu na faịlụ service.q) wee kpọọ ọrụ init:
q service.q –p 5566
q)init[]
Na njikwa ọzọ, malite usoro Q nke abụọ wee jikọọ na nke mbụ:
h:hopen `:host:5566
h:hopen 5566 // если оба на одном хосте
Mbụ, ka anyị mepụta ndepụta nke akara - 10000 iberibe ma tinye ọrụ iji mepụta tebụl na-enweghị usoro. Na console nke abụọ:
syms:`IBM`AAPL`GOOG,-9997?`8
rnd:{[n;t] ([] sym:n?syms; time:t+asc n#til 25; price:n?10f; size:n?10)}
M gbakwunyere ezigbo akara atọ na ndepụta ahụ iji mee ka ọ dịkwuo mfe ịchọ ha na tebụl. Ọrụ rnd na-emepụta tebụl na-enweghị usoro nwere ahịrị n, ebe oge dị iche site na t ruo t+25 milliseconds.
Ugbu a ị nwere ike ịnwale izipu data na ọrụ ahụ (tinye awa iri mbụ):
{h (`upd;`trade;rnd[10000;x])} each `time$00:00 + til 60*10
Ị nwere ike ịlele na ọrụ ahụ na emelitela tebụl:
c 25 200
select from tradeAgg where sym=`AAPL
-20#select from tradeAgg where sym=`AAPL
Nsonaazụ:
sym|time|high|low|firstPrice|lastPrice|firstSize|lastSize|numTrades|volume|pvolume|turnover|avgPrice|avgSize|vwap|cumVolume
--|--|--|--|--|--------------------------------
AAPL|09:27|9.258904|9.258904|9.258904|9.258904|8|8|1|8|9.258904|74.07123|9.258904|8|9.258904|2888
AAPL|09:28|9.068162|9.068162|9.068162|9.068162|7|7|1|7|9.068162|63.47713|9.068162|7|9.068162|2895
AAPL|09:31|4.680449|0.2011121|1.620827|0.2011121|1|5|4|14|9.569556|36.84342|2.392389|3.5|2.631673|2909
AAPL|09:33|2.812535|2.812535|2.812535|2.812535|6|6|1|6|2.812535|16.87521|2.812535|6|2.812535|2915
AAPL|09:34|5.099025|5.099025|5.099025|5.099025|4|4|1|4|5.099025|20.3961|5.099025|4|5.099025|2919Ka anyị mee nnwale nnwale ugbu a iji chọpụta data ole ọrụ nwere ike ịhazi kwa nkeji. Ka m chetara gị na anyị debere oge mmelite ahụ ka ọ bụrụ millisek 25. N'ihi ya, ọrụ ahụ ga- (na nkezi) dabara n'ime opekata mpe 20 milliseconds kwa mmelite iji nye ndị ọrụ oge ịrịọ data. Tinye ihe ndị a na usoro nke abụọ:
tm:10:00:00.000
stressTest:{[n] 1 string[tm]," "; times,::h ({st:.z.T; upd[`trade;x]; .z.T-st};rnd[n;tm]); tm+:25}
start:{[n] times::(); do[4800;stressTest[n]]; -1 " "; `min`avg`med`max!(min times;avg times;med times;max times)}
4800 bụ nkeji abụọ. Ị nwere ike ịnwa ịgba ọsọ maka 1000 ahịrị kwa millisek 25 ọ bụla:
start 1000
N'ọnọdụ m, nsonaazụ ya dị ihe dị ka milliseconds abụọ kwa mmelite. Yabụ na m ga-abawanye ọnụ ọgụgụ ahịrị ozugbo ka ọ bụrụ 10.000:
start 10000
Nsonaazụ:
min| 00:00:00.004
avg| 9.191458
med| 9f
max| 00:00:00.030
Ọzọ, ọ dịghị ihe pụrụ iche, ma nke a bụ 24 nde ahịrị kwa nkeji, 400 puku kwa sekọnd. Maka ihe karịrị 25 milliseconds, mmelite ahụ kwụsịrị naanị ugboro 5, o doro anya mgbe nkeji gbanwere. Ka anyị gbasaa ruo 100.000:
start 100000
Nsonaazụ:
min| 00:00:00.013
avg| 25.11083
med| 24f
max| 00:00:00.108
q)sum times
00:02:00.532
Dị ka ị na-ahụ, ọrụ ahụ nwere ike ịnagide ya, mana ka o sina dị, ọ na-achịkwa ịnọgide na-ese n'elu mmiri. Ọnụ ọgụgụ dị otú ahụ nke data (240 nde ahịrị kwa nkeji) dị oke ibu; n'ọnọdụ ndị dị otú ahụ, a na-emekarị ọtụtụ clones (ma ọ bụ ọbụna ọtụtụ clones) nke ọrụ ahụ, nke ọ bụla n'ime ha na-eme naanị akụkụ nke ihe odide. N'agbanyeghị nke ahụ, nsonaazụ ya na-adọrọ mmasị maka asụsụ atụgharịrị nke gbadoro anya na nchekwa data.
Ajụjụ nwere ike ibilite maka ihe kpatara na oge na-etolite na-abụghị linearly na nha nke mmelite ọ bụla. Ihe kpatara ya bụ na ọrụ nkwụsịtụ bụ n'ezie ọrụ C, nke na-arụ ọrụ nke ọma karịa updateAgg. Malite na ụfọdụ mmelite nha (ihe dị ka 10.000), updateAgg rutere n'uko ụlọ ya ma oge igbu ya adabereghị na nha mmelite ahụ. Ọ bụ n'ihi nzọụkwụ mbụ Q na ọrụ ahụ nwere ike igbari ụdị data dị otú ahụ. Nke a na-eme ka ọ pụta ìhè na ọ dị mkpa ịhọrọ algorithm ziri ezi mgbe ị na-arụ ọrụ na nnukwu data. Isi ihe ọzọ bụ nchekwa data ziri ezi na ebe nchekwa. Ọ bụrụ na echekwaghị data ahụ na kọlụm ma ọ bụ na enyeghị ya iwu site na oge, mgbe ahụ anyị ga-amata ihe dị ka TLB cache miss - enweghị adreesị ibe ebe nchekwa na cache adreesị processor. Ịchọ adreesị na-ewe ihe dị ka ugboro 30 ma ọ bụrụ na ọ gaghị eme nke ọma, ma ọ bụrụ na agbasasịwo data ahụ, ọ nwere ike belata ọrụ ahụ ọtụtụ oge.
nkwubi
N'isiokwu a, egosiri m na nchekwa data KDB + na Q dabara adaba ọ bụghị naanị maka ịchekwa nnukwu data na ịnweta ya ngwa ngwa site na ịhọrọ, kamakwa maka ịmepụta ọrụ nhazi data nke nwere ike igbari ọtụtụ narị nde ahịrị / gigabytes nke data ọbụna na. otu usoro Q. Asụsụ Q n'onwe ya na-enye ohere maka mmejuputa algọridim dị nkenke na nke ọma nke metụtara nhazi data n'ihi ọdịdị vector ya, onye ntụgharị asụsụ SQL arụnyere n'ime ya yana ọrụ ọbá akwụkwọ na-aga nke ọma.
M ga-achọpụta na nke a dị n'elu bụ akụkụ nke ihe Q nwere ike ime, ọ nwekwara ihe ndị ọzọ pụrụ iche. Dịka ọmụmaatụ, usoro IPC dị mfe nke na-ehichapụ oke n'etiti usoro Q nke ọ bụla ma na-enye gị ohere ijikọta ọtụtụ narị usoro ndị a n'ime otu netwọkụ, nke nwere ike ịdị na ọtụtụ sava n'akụkụ dị iche iche nke ụwa.
isi: www.habr.com
