校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識庫 > 在PostgreSQL中使用數(shù)組時值得注意的一些地方

在PostgreSQL中使用數(shù)組時值得注意的一些地方

熱門標簽:南昌呼叫中心外呼系統(tǒng)哪家好 怎么去開發(fā)一個電銷機器人 小程序智能電話機器人 ai電話電話機器人 泗洪正規(guī)電話機器人找哪家 湖南保險智能外呼系統(tǒng)產(chǎn)品介紹 怎么申請400熱線電話 簡單的智能語音電銷機器人 河北便宜電銷機器人軟件

在Heap中,我們依靠PostgreSQL支撐大多數(shù)后端繁重的任務,我們存儲每個事件為一個hstore blob,我們?yōu)槊總€跟蹤的用戶維護一個已完成事件的PostgreSQL數(shù)組,并將這些事件按時間排序。 Hstore能夠讓我們以靈活的方式附加屬性到事件中,而且事件數(shù)組賦予了我們強大的性能,特別是對于漏斗查詢,在這些查詢中我們計算不同轉化渠道步驟間的輸出。

在這篇文章中,我們看看那些意外接受大量輸入的PostgreSQL函數(shù),然后以高效,慣用的方式重寫它。

你的第一反應可能是將PostgreSQL中的數(shù)組看做像C語言中對等的類似物。你之前可能用過變換陣列位置或切片來操縱數(shù)據(jù)。不過要小心,在PostgreSQL中不要有這樣的想法,特別是數(shù)組類型是變長的時,比如JSON、文本或是hstore。如果你通過位置來訪問PostgreSQL數(shù)組,你會進入一個意想不到的性能暴跌的境地。


這種情況幾星期前在Heap出現(xiàn)了。我們在Heap為每個跟蹤用戶維護一個事件數(shù)組,在這個數(shù)組中我們用一個hstore datum代表每個事件。我們有一個導入管道來追加新事件到對應的數(shù)組。為了使這一導入管道是冪等的,我們給每個事件設定一個event_id,我們通過一個功能函數(shù)重復運行我們的事件數(shù)組。如果我們要更新附加到事件的屬性的話,我們只需使用相同的event_id轉儲一個新的事件到管道中。

所以,我們需要一個功能函數(shù)來處理hstores數(shù)組,并且,如果兩個事件具有相同的event_id時應該使用數(shù)組中最近出現(xiàn)的那個。剛開始嘗試這個函數(shù)是這樣寫的:
 

-- This is slow, and you don't want to use it!
--
-- Filter an array of events such that there is only one event with each event_id.
-- When more than one event with the same event_id is present, take the latest one.
CREATE OR REPLACE FUNCTION dedupe_events_1(events HSTORE[]) RETURNS HSTORE[] AS $$
 SELECT array_agg(event)
 FROM (
  -- Filter for rank = 1, i.e. select the latest event for any collisions on event_id.
  SELECT event
  FROM (
   -- Rank elements with the same event_id by position in the array, descending.

這個查詢在擁有2.4GHz的i7CPU及16GB Ram的macbook pro上測得,運行腳本為:https://gist.github.com/drob/9180760。


在這邊究竟發(fā)生了什么呢? 關鍵在于PostgreSQL存貯了一個系列的hstores作為數(shù)組的值, 而不是指向值的指針. 一個包含了三個hstores的數(shù)組看起來像

{“event_id=>1,data=>foo”, “event_id=>2,data=>bar”, “event_id=>3,data=>baz”}

相反的是

{[pointer], [pointer], [pointer]}

 

對于那些長度不一的變量, 舉個例子. hstores, json blobs, varchars,或者是 text fields, PostgreSQL 必須去找到每一個變量的長度. 對于evaluateevents[2], PostgreSQL 解析從左側讀取的事件直到讀取到第二次讀取的數(shù)據(jù). 然后就是 forevents[3], 她再一次的從第一個索引處開始掃描,直到讀到第三次的數(shù)據(jù)! 所以, evaluatingevents[sub]是 O(sub), 并且 evaluatingevents[sub]對于在數(shù)組中的每一個索引都是 O(N2), N是數(shù)組的長度.

PostgreSQL能得到更加恰當?shù)慕馕鼋Y果,  它可以在這樣的情況下分析該數(shù)組一次. 真正的答案是可變長度的元素與指針來實現(xiàn),以數(shù)組的值, 以至于,我們總能夠處理 evaluateevents[i]在不變的時間內.


即便如此,我們也不應該讓PostgreSQL來處理,因為這不是一個地道的查詢。除了generate_subscripts我們可以用unnest,它解析數(shù)組并返回一組條目。這樣一來,我們就不需要在數(shù)組中顯式加入索引了。
 

-- Filter an array of events such that there is only one event with each event_id.
-- When more than one event with the same event_id, is present, take the latest one.
CREATE OR REPLACE FUNCTION dedupe_events_2(events HSTORE[]) RETURNS HSTORE[] AS $$
 SELECT array_agg(event)
 FROM (
  -- Filter for rank = 1, i.e. select the latest event for any collisions on event_id.
  SELECT event
  FROM (
   -- Rank elements with the same event_id by position in the array, descending.
   SELECT event, row_number AS index, rank()
   OVER (PARTITION BY (event -> 'event_id')::BIGINT ORDER BY row_number DESC)
   FROM (
    -- Use unnest instead of generate_subscripts to turn an array into a set.
    SELECT event, row_number()
    OVER (ORDER BY event -> 'time')
    FROM unnest(events) AS event
   ) unnested_data
  ) deduped_events
  WHERE rank = 1
  ORDER BY index ASC
 ) to_agg;
$$ LANGUAGE SQL IMMUTABLE;

結果是有效的,它花費的時間跟輸入數(shù)組的大小呈線性關系。對于100K個元素的輸入它需要大約半秒,而之前的實現(xiàn)需要40秒。

這實現(xiàn)了我們的需求:

  •     一次解析數(shù)組,不需要unnest。
  •     按event_id劃分。
  •     對每個event_id采用最新出現(xiàn)的。
  •     按輸入索引排序。

教訓:如果你需要訪問PostgreSQL數(shù)組的特定位置,考慮使用unnest代替。 

   SELECT events[sub] AS event, sub, rank()
   OVER (PARTITION BY (events[sub] -> 'event_id')::BIGINT ORDER BY sub DESC)
   FROM generate_subscripts(events, 1) AS sub
  ) deduped_events
  WHERE rank = 1
  ORDER BY sub ASC
 ) to_agg;
$$ LANGUAGE SQL IMMUTABLE;

這樣奏效,但大輸入是性能下降了。這是二次的,在輸入數(shù)組有100K各元素時它需要大約40秒!

這個查詢在擁有2.4GHz的i7CPU及16GB Ram的macbook pro上測得,運行腳本為:https://gist.github.com/drob/9180760。


在這邊究竟發(fā)生了什么呢? 關鍵在于PostgreSQL存貯了一個系列的hstores作為數(shù)組的值, 而不是指向值的指針. 一個包含了三個hstores的數(shù)組看起來像

{“event_id=>1,data=>foo”, “event_id=>2,data=>bar”, “event_id=>3,data=>baz”}

相反的是

{[pointer], [pointer], [pointer]}

 

對于那些長度不一的變量, 舉個例子. hstores, json blobs, varchars,或者是 text fields, PostgreSQL 必須去找到每一個變量的長度. 對于evaluateevents[2], PostgreSQL 解析從左側讀取的事件直到讀取到第二次讀取的數(shù)據(jù). 然后就是 forevents[3], 她再一次的從第一個索引處開始掃描,直到讀到第三次的數(shù)據(jù)! 所以, evaluatingevents[sub]是 O(sub), 并且 evaluatingevents[sub]對于在數(shù)組中的每一個索引都是 O(N2), N是數(shù)組的長度.

PostgreSQL能得到更加恰當?shù)慕馕鼋Y果,  它可以在這樣的情況下分析該數(shù)組一次. 真正的答案是可變長度的元素與指針來實現(xiàn),以數(shù)組的值, 以至于,我們總能夠處理 evaluateevents[i]在不變的時間內.


即便如此,我們也不應該讓PostgreSQL來處理,因為這不是一個地道的查詢。除了generate_subscripts我們可以用unnest,它解析數(shù)組并返回一組條目。這樣一來,我們就不需要在數(shù)組中顯式加入索引了。
 

-- Filter an array of events such that there is only one event with each event_id.
-- When more than one event with the same event_id, is present, take the latest one.
CREATE OR REPLACE FUNCTION dedupe_events_2(events HSTORE[]) RETURNS HSTORE[] AS $$
 SELECT array_agg(event)
 FROM (
  -- Filter for rank = 1, i.e. select the latest event for any collisions on event_id.
  SELECT event
  FROM (
   -- Rank elements with the same event_id by position in the array, descending.
   SELECT event, row_number AS index, rank()
   OVER (PARTITION BY (event -> 'event_id')::BIGINT ORDER BY row_number DESC)
   FROM (
    -- Use unnest instead of generate_subscripts to turn an array into a set.
    SELECT event, row_number()
    OVER (ORDER BY event -> 'time')
    FROM unnest(events) AS event
   ) unnested_data
  ) deduped_events
  WHERE rank = 1
  ORDER BY index ASC
 ) to_agg;
$$ LANGUAGE SQL IMMUTABLE;

結果是有效的,它花費的時間跟輸入數(shù)組的大小呈線性關系。對于100K個元素的輸入它需要大約半秒,而之前的實現(xiàn)需要40秒。

這實現(xiàn)了我們的需求:

  •     一次解析數(shù)組,不需要unnest。
  •     按event_id劃分。
  •     對每個event_id采用最新出現(xiàn)的。
  •     按輸入索引排序。

教訓:如果你需要訪問PostgreSQL數(shù)組的特定位置,考慮使用unnest代替。

您可能感興趣的文章:
  • PostgreSQL 對數(shù)組的遍歷操作
  • PostgreSQL中使用數(shù)組改進性能實例代碼
  • Mybatis調用PostgreSQL存儲過程實現(xiàn)數(shù)組入?yún)鬟f
  • postgresql 實現(xiàn)將數(shù)組變?yōu)樾?/li>

標簽:景德鎮(zhèn) 荊門 柳州 淮安 威海 瀘州 江蘇 那曲

巨人網(wǎng)絡通訊聲明:本文標題《在PostgreSQL中使用數(shù)組時值得注意的一些地方》,本文關鍵詞  在,PostgreSQL,中,使用,數(shù)組,;如發(fā)現(xiàn)本文內容存在版權問題,煩請?zhí)峁┫嚓P信息告之我們,我們將及時溝通與處理。本站內容系統(tǒng)采集于網(wǎng)絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《在PostgreSQL中使用數(shù)組時值得注意的一些地方》相關的同類信息!
  • 本頁收集關于在PostgreSQL中使用數(shù)組時值得注意的一些地方的相關信息資訊供網(wǎng)民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    中文字幕成人av| 亚洲图片自拍偷拍| 中文幕一区二区三区久久蜜桃| 蜜臀久久99精品久久久久久9| 7777精品伊人久久久大香线蕉最新版 | 欧美区在线观看| 蜜桃一区二区三区在线| 久久久www成人免费毛片麻豆| 成人av免费观看| 天天综合色天天综合| 久久亚洲捆绑美女| 91免费视频网址| 久久99国内精品| 亚洲伦在线观看| 亚洲精品一线二线三线无人区| 成人18视频日本| 日本美女视频一区二区| 国产视频一区二区在线| 色天天综合色天天久久| 国产真实乱偷精品视频免| 亚洲免费高清视频在线| 久久色.com| 欧美日韩精品一区二区三区| 国产成人av福利| 日本在线不卡一区| 亚洲精品少妇30p| 亚洲精品在线一区二区| 一本大道综合伊人精品热热| 久久99国产精品久久| 亚洲在线成人精品| 国产欧美日韩在线| 日韩美女视频一区二区在线观看| a亚洲天堂av| 狠狠色综合日日| 视频一区在线播放| 亚洲最色的网站| 最新欧美精品一区二区三区| 久久精品综合网| 久久精品人人做| 精品免费99久久| 日韩欧美在线观看一区二区三区| 色综合天天综合给合国产| 成人小视频在线| 国产一区二区三区| 麻豆视频一区二区| 日本vs亚洲vs韩国一区三区 | 自拍偷自拍亚洲精品播放| 久久嫩草精品久久久精品一| 91精品国产福利| 日韩欧美在线影院| 欧美成人一区二区三区片免费| 欧美日本不卡视频| 欧美日韩高清不卡| 欧美另类高清zo欧美| 91精品国产一区二区三区香蕉| 欧美午夜电影在线播放| 欧美日韩免费高清一区色橹橹| 99精品视频中文字幕| 成人午夜精品一区二区三区| 91丨九色丨蝌蚪富婆spa| 成人免费视频播放| 91小视频免费看| 欧美三级日韩三级| 欧美日韩一区二区三区在线| 日韩午夜小视频| 久久久久久综合| 国产精品久久精品日日| 亚洲免费观看高清| 亚洲精品一区二区三区影院| 一区二区激情小说| 97久久精品人人爽人人爽蜜臀| 国产毛片精品一区| 欧美精品乱码久久久久久按摩| 99久久伊人精品| 一本一道综合狠狠老| 无码av中文一区二区三区桃花岛| 亚洲黄色性网站| 日本在线不卡视频| 国产乱人伦偷精品视频不卡| 99国产精品久久久久久久久久 | 国产日韩av一区二区| 日韩在线观看一区二区| 日本不卡在线视频| 午夜精品免费在线观看| 久久久国产一区二区三区四区小说| 成人av网站大全| 国产成人丝袜美腿| 欧美美女视频在线观看| 国产精品入口麻豆原神| 色欲综合视频天天天| 久久成人免费网| 国产精品初高中害羞小美女文| 色噜噜狠狠色综合欧洲selulu| 午夜av区久久| **欧美大码日韩| 日韩一区二区三| 在线亚洲一区二区| 国产在线精品一区在线观看麻豆| 亚洲激情校园春色| 国产日产欧美一区二区三区| 色婷婷av一区二区三区之一色屋| 久久99精品国产麻豆婷婷洗澡| 亚洲免费色视频| 日韩欧美aaaaaa| 久久人人97超碰com| 国产成都精品91一区二区三| 精品一区免费av| 国产一区二区三区美女| 麻豆国产欧美一区二区三区| 五月综合激情婷婷六月色窝| 亚洲成人免费电影| 亚洲成人1区2区| 日本中文字幕不卡| 美女视频黄 久久| 激情另类小说区图片区视频区| 麻豆免费看一区二区三区| 午夜影院久久久| 天堂午夜影视日韩欧美一区二区| 日韩中文字幕区一区有砖一区 | 99久久精品国产一区| 国产自产高清不卡| 成人性生交大片免费看视频在线 | 一区二区三区高清在线| 欧美国产97人人爽人人喊| 美脚の诱脚舐め脚责91| 国精产品一区一区三区mba桃花 | 国产精品久久久久久一区二区三区| 久久久久成人黄色影片| 亚洲精品亚洲人成人网| 九色综合狠狠综合久久| av在线不卡免费看| 欧美v日韩v国产v| 国产性天天综合网| 综合久久久久久| 国产成人在线影院| 国产精品午夜电影| 视频一区视频二区中文字幕| 风间由美中文字幕在线看视频国产欧美| 国产成人在线色| 欧美一区二区三区在线| 中文字幕中文乱码欧美一区二区| 亚洲mv在线观看| 在线观看欧美精品| 久久久精品天堂| 午夜精品久久久久久久久久| 91小视频在线| 欧美三级日韩三级| 国模无码大尺度一区二区三区| 91网站在线观看视频| 国产精品初高中害羞小美女文| 国产精品一级在线| 久久久久久**毛片大全| 豆国产96在线|亚洲| 久久亚洲二区三区| 成人一区在线观看| 欧美激情综合五月色丁香小说| 亚洲精品你懂的| 欧美在线三级电影| 亚洲猫色日本管| 不卡一区在线观看| 91在线观看下载| 欧美国产成人精品| 欧美午夜精品免费| 日日欢夜夜爽一区| 国产精品一区二区三区网站| 精品国产a毛片| 国产精品色哟哟网站| 久久99久久99精品免视看婷婷 | 日本乱人伦aⅴ精品| 精品在线亚洲视频| 精品一区二区三区视频在线观看 | www.日韩在线| 国产黑丝在线一区二区三区| 亚洲男人的天堂在线观看| 国产99久久久久| 成人av网站在线观看| 成人av一区二区三区| 91免费看视频| 日韩精品一区二区三区四区视频| 欧美精品自拍偷拍| 国产婷婷色一区二区三区四区 | 视频一区二区中文字幕| 天堂蜜桃一区二区三区| 精品在线你懂的| 色哟哟精品一区| 2023国产精品自拍| 亚洲精品国产高清久久伦理二区| 午夜亚洲福利老司机| 国产成人综合在线播放| 91久久国产最好的精华液| 日韩久久免费av| 亚洲www啪成人一区二区麻豆| 国产一区二区视频在线| 欧洲生活片亚洲生活在线观看| 欧美人与z0zoxxxx视频| 亚洲女子a中天字幕| 国产在线精品一区二区不卡了 | 亚洲电影在线播放| 丁香激情综合国产| 日韩女优毛片在线|