正确使用 PostgreSQL 的数组类型

在Heap中,我们依靠PostgreSQL支撑大多数后端繁重的任务,我们存储每个事件为一个hstore blob,我们为每个跟踪的用户维护一个已完成事件的PostgreSQL数组,并将这些事件按时间排序。 Hstore能够让我们以灵活的方式附加属性到事件中,而且事件数组赋予了我们强大的性能,特别是对于漏斗查询,在这些查询中我们计算不同转化渠道步骤间的输出。

在这篇文章中,我们看看那些意外接受大量输入的PostgreSQL函数,然后以高效,惯用的方式重写它。 

你的第一反应可能是将PostgreSQL中的数组看做像C语言中对等的类似物。你之前可能用过变换阵列位置或切片来操纵数据。不过要小心,在PostgreSQL中不要有这样的想法,特别是数组类型是变长的时,比如JSON、文本或是hstore。如果你通过位置来访问PostgreSQL数组,你会进入一个意想不到的性能暴跌的境地。

Garfielt
Garfielt
翻译于 2014/02/27 08:43
 
这种情况几星期前在Heap出现了。我们在Heap为每个跟踪用户维护一个事件数组,在这个数组中我们用一个hstore datum代表每个事件。我们有一个导入管道来追加新事件到对应的数组。为了使这一导入管道是幂等的,我们给每个事件设定一个event_id,我们通过一个功能函数重复运行我们的事件数组。如果我们要更新附加到事件的属性的话,我们只需使用相同的event_id转储一个新的事件到管道中。 

所以,我们需要一个功能函数来处理hstores数组,并且,如果两个事件具有相同的event_id时应该使用数组中最近出现的那个。刚开始尝试这个函数是这样写的:

-- 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.
      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;
这样奏效,但大输入是性能下降了。这是二次的,在输入数组有100K各元素时它需要大约40秒!

http://blog.tianya.cn/blog-7805374-1.shtml
http://blog.tianya.cn/blog-7805375-1.shtml
http://blog.tianya.cn/blog-7805376-1.shtml
http://blog.tianya.cn/blog-7805377-1.shtml
http://blog.tianya.cn/blog-7805378-1.shtml
http://blog.tianya.cn/blog-7805379-1.shtml
http://blog.tianya.cn/blog-7805380-1.shtml
http://blog.tianya.cn/blog-7805381-1.shtml
http://blog.tianya.cn/blog-7805383-1.shtml
http://blog.tianya.cn/blog-7805384-1.shtml
http://blog.tianya.cn/blog-7805385-1.shtml
http://blog.tianya.cn/blog-7805387-1.shtml
http://blog.tianya.cn/blog-7805388-1.shtml
http://blog.tianya.cn/blog-7805389-1.shtml
http://blog.tianya.cn/blog-7805390-1.shtml
http://blog.tianya.cn/blog-7805391-1.shtml
http://blog.tianya.cn/blog-7805392-1.shtml
http://blog.tianya.cn/blog-7805393-1.shtml
http://blog.tianya.cn/blog-7805394-1.shtml
http://blog.tianya.cn/blog-7805395-1.shtml
http://blog.tianya.cn/blog-7805396-1.shtml
http://blog.tianya.cn/blog-7805398-1.shtml
http://blog.tianya.cn/blog-7805399-1.shtml
http://blog.tianya.cn/blog-7805400-1.shtml
http://blog.tianya.cn/blog-7805402-1.shtml
http://blog.tianya.cn/blog-7805403-1.shtml
http://blog.tianya.cn/blog-7805404-1.shtml
http://blog.tianya.cn/blog-7805405-1.shtml
http://blog.tianya.cn/blog-7805406-1.shtml
http://blog.tianya.cn/blog-7805407-1.shtml
http://blog.tianya.cn/blog-7805409-1.shtml
http://blog.tianya.cn/blog-7805410-1.shtml
http://blog.tianya.cn/blog-7805411-1.shtml
http://blog.tianya.cn/blog-7805412-1.shtml
http://blog.tianya.cn/blog-7805413-1.shtml
http://blog.tianya.cn/blog-7805415-1.shtml
http://blog.tianya.cn/blog-7805416-1.shtml
http://blog.tianya.cn/blog-7805417-1.shtml
http://blog.tianya.cn/blog-7805418-1.shtml
http://blog.tianya.cn/blog-7805419-1.shtml
http://blog.tianya.cn/blog-7805421-1.shtml
http://blog.tianya.cn/blog-7805423-1.shtml
http://blog.tianya.cn/blog-7805424-1.shtml
http://blog.tianya.cn/blog-7805425-1.shtml
http://blog.tianya.cn/blog-7805426-1.shtml
http://blog.tianya.cn/blog-7805427-1.shtml
http://blog.tianya.cn/blog-7805428-1.shtml
http://blog.tianya.cn/blog-7805429-1.shtml
http://blog.tianya.cn/blog-7805431-1.shtml
http://blog.tianya.cn/blog-7805432-1.shtml
http://blog.tianya.cn/blog-7805433-1.shtml
http://blog.tianya.cn/blog-7805434-1.shtml
http://blog.tianya.cn/blog-7805435-1.shtml
http://blog.tianya.cn/blog-7805436-1.shtml
http://blog.tianya.cn/blog-7805437-1.shtml
http://blog.tianya.cn/blog-7805438-1.shtml
http://blog.tianya.cn/blog-7805439-1.shtml
http://blog.tianya.cn/blog-7805440-1.shtml
http://blog.tianya.cn/blog-7805441-1.shtml
http://blog.tianya.cn/blog-7805442-1.shtml
http://blog.tianya.cn/blog-7805443-1.shtml
http://blog.tianya.cn/blog-7805444-1.shtml
http://blog.tianya.cn/blog-7805445-1.shtml
http://blog.tianya.cn/blog-7805446-1.shtml
http://blog.tianya.cn/blog-7805448-1.shtml
http://blog.tianya.cn/blog-7805449-1.shtml
http://blog.tianya.cn/blog-7805450-1.shtml
http://blog.tianya.cn/blog-7805451-1.shtml
http://blog.tianya.cn/blog-7805453-1.shtml
http://blog.tianya.cn/blog-7805454-1.shtml
http://blog.tianya.cn/blog-7805455-1.shtml
http://blog.tianya.cn/blog-7805456-1.shtml
http://blog.tianya.cn/blog-7805457-1.shtml
http://blog.tianya.cn/blog-7805458-1.shtml
http://blog.tianya.cn/blog-7805460-1.shtml
http://blog.tianya.cn/blog-7805461-1.shtml
http://blog.tianya.cn/blog-7805462-1.shtml
http://blog.tianya.cn/blog-7805463-1.shtml
http://blog.tianya.cn/blog-7805464-1.shtml
http://blog.tianya.cn/blog-7805465-1.shtml
http://blog.tianya.cn/blog-7805466-1.shtml
http://blog.tianya.cn/blog-7805467-1.shtml
http://blog.tianya.cn/blog-7805468-1.shtml
http://blog.tianya.cn/blog-7805469-1.shtml
http://blog.tianya.cn/blog-7805470-1.shtml
http://blog.tianya.cn/blog-7805471-1.shtml
http://blog.tianya.cn/blog-7805472-1.shtml
http://blog.tianya.cn/blog-7805473-1.shtml
http://blog.tianya.cn/blog-7805475-1.shtml
http://blog.tianya.cn/blog-7805476-1.shtml
http://blog.tianya.cn/blog-7805477-1.shtml
http://blog.tianya.cn/blog-7805478-1.shtml
http://blog.tianya.cn/blog-7805479-1.shtml
http://blog.tianya.cn/blog-7805480-1.shtml
http://blog.tianya.cn/blog-7805481-1.shtml
http://blog.tianya.cn/blog-7805482-1.shtml
http://blog.tianya.cn/blog-7805483-1.shtml
http://blog.tianya.cn/blog-7805484-1.shtml
http://blog.tianya.cn/blog-7805485-1.shtml
http://blog.tianya.cn/blog-7805487-1.shtml
http://blog.tianya.cn/blog-7805491-1.shtml
http://blog.tianya.cn/blog-7805493-1.shtml
http://blog.tianya.cn/post-7805374-131365428-1.shtml
http://blog.tianya.cn/post-7805374-131365429-1.shtml
http://blog.tianya.cn/post-7805374-131365430-1.shtml
http://blog.tianya.cn/post-7805375-131365431-1.shtml
http://blog.tianya.cn/post-7805375-131365432-1.shtml
http://blog.tianya.cn/post-7805375-131365433-1.shtml
http://blog.tianya.cn/post-7805376-131365435-1.shtml
http://blog.tianya.cn/post-7805376-131365436-1.shtml
http://blog.tianya.cn/post-7805376-131365437-1.shtml
http://blog.tianya.cn/post-7805377-131365439-1.shtml
http://blog.tianya.cn/post-7805377-131365440-1.shtml
http://blog.tianya.cn/post-7805377-131365441-1.shtml
http://blog.tianya.cn/post-7805378-131365443-1.shtml
http://blog.tianya.cn/post-7805378-131365444-1.shtml
http://blog.tianya.cn/post-7805378-131365445-1.shtml
http://blog.tianya.cn/post-7805379-131365447-1.shtml
http://blog.tianya.cn/post-7805379-131365448-1.shtml
http://blog.tianya.cn/post-7805379-131365449-1.shtml
http://blog.tianya.cn/post-7805380-131365450-1.shtml
http://blog.tianya.cn/post-7805380-131365451-1.shtml
http://blog.tianya.cn/post-7805380-131365452-1.shtml
http://blog.tianya.cn/post-7805381-131365453-1.shtml
http://blog.tianya.cn/post-7805381-131365454-1.shtml
http://blog.tianya.cn/post-7805381-131365455-1.shtml
http://blog.tianya.cn/post-7805383-131365456-1.shtml
http://blog.tianya.cn/post-7805383-131365457-1.shtml
http://blog.tianya.cn/post-7805383-131365458-1.shtml
http://blog.tianya.cn/post-7805384-131365462-1.shtml
http://blog.tianya.cn/post-7805384-131365463-1.shtml
http://blog.tianya.cn/post-7805384-131365464-1.shtml
http://blog.tianya.cn/post-7805385-131365465-1.shtml
http://blog.tianya.cn/post-7805385-131365466-1.shtml
http://blog.tianya.cn/post-7805385-131365467-1.shtml
http://blog.tianya.cn/post-7805387-131365468-1.shtml
http://blog.tianya.cn/post-7805387-131365469-1.shtml
http://blog.tianya.cn/post-7805387-131365470-1.shtml
http://blog.tianya.cn/post-7805388-131365473-1.shtml
http://blog.tianya.cn/post-7805388-131365474-1.shtml
http://blog.tianya.cn/post-7805388-131365475-1.shtml
http://blog.tianya.cn/post-7805389-131365476-1.shtml
http://blog.tianya.cn/post-7805389-131365477-1.shtml
http://blog.tianya.cn/post-7805389-131365478-1.shtml
http://blog.tianya.cn/post-7805390-131365479-1.shtml
http://blog.tianya.cn/post-7805391-131365484-1.shtml
http://blog.tianya.cn/post-7805391-131365485-1.shtml
http://blog.tianya.cn/post-7805391-131365486-1.shtml
http://blog.tianya.cn/post-7805392-131365487-1.shtml
http://blog.tianya.cn/post-7805392-131365488-1.shtml
http://blog.tianya.cn/post-7805392-131365490-1.shtml
http://blog.tianya.cn/post-7805393-131365493-1.shtml
http://blog.tianya.cn/post-7805393-131365494-1.shtml
http://blog.tianya.cn/post-7805393-131365495-1.shtml
http://blog.tianya.cn/post-7805394-131365497-1.shtml
http://blog.tianya.cn/post-7805394-131365498-1.shtml
http://blog.tianya.cn/post-7805394-131365499-1.shtml
http://blog.tianya.cn/post-7805395-131365502-1.shtml
http://blog.tianya.cn/post-7805395-131365505-1.shtml
http://blog.tianya.cn/post-7805395-131365508-1.shtml
http://blog.tianya.cn/post-7805396-131365510-1.shtml
http://blog.tianya.cn/post-7805396-131365511-1.shtml
http://blog.tianya.cn/post-7805396-131365512-1.shtml
http://blog.tianya.cn/post-7805398-131365516-1.shtml
http://blog.tianya.cn/post-7805398-131365519-1.shtml
http://blog.tianya.cn/post-7805398-131365521-1.shtml
http://blog.tianya.cn/post-7805399-131365522-1.shtml
http://blog.tianya.cn/post-7805399-131365523-1.shtml
http://blog.tianya.cn/post-7805399-131365524-1.shtml
http://blog.tianya.cn/post-7805400-131365526-1.shtml
http://blog.tianya.cn/post-7805400-131365527-1.shtml
http://blog.tianya.cn/post-7805400-131365528-1.shtml
http://blog.tianya.cn/post-7805402-131365534-1.shtml
http://blog.tianya.cn/post-7805402-131365535-1.shtml
http://blog.tianya.cn/post-7805402-131365538-1.shtml
http://blog.tianya.cn/post-7805403-131365540-1.shtml
http://blog.tianya.cn/post-7805403-131365546-1.shtml
http://blog.tianya.cn/post-7805403-131365549-1.shtml
http://blog.tianya.cn/post-7805404-131365552-1.shtml
http://blog.tianya.cn/post-7805404-131365553-1.shtml
http://blog.tianya.cn/post-7805404-131365555-1.shtml
http://blog.tianya.cn/post-7805405-131365556-1.shtml
http://blog.tianya.cn/post-7805405-131365557-1.shtml
http://blog.tianya.cn/post-7805405-131365558-1.shtml
http://blog.tianya.cn/post-7805406-131365560-1.shtml
http://blog.tianya.cn/post-7805406-131365561-1.shtml
http://blog.tianya.cn/post-7805406-131365562-1.shtml
http://blog.tianya.cn/post-7805407-131365565-1.shtml
http://blog.tianya.cn/post-7805407-131365570-1.shtml
http://blog.tianya.cn/post-7805409-131365572-1.shtml
http://blog.tianya.cn/post-7805409-131365574-1.shtml
http://blog.tianya.cn/post-7805409-131365575-1.shtml
http://blog.tianya.cn/post-7805410-131365579-1.shtml
http://blog.tianya.cn/post-7805410-131365580-1.shtml
http://blog.tianya.cn/post-7805410-131365581-1.shtml
http://blog.tianya.cn/post-7805411-131365588-1.shtml
http://blog.tianya.cn/post-7805411-131365590-1.shtml
http://blog.tianya.cn/post-7805411-131365591-1.shtml
http://blog.tianya.cn/post-7805412-131365593-1.shtml
http://blog.tianya.cn/post-7805412-131365595-1.shtml
http://blog.tianya.cn/post-7805412-131365596-1.shtml
http://blog.tianya.cn/post-7805413-131365599-1.shtml
http://blog.tianya.cn/post-7805413-131365601-1.shtml
http://blog.tianya.cn/post-7805413-131365602-1.shtml
http://blog.tianya.cn/post-7805415-131365605-1.shtml
http://blog.tianya.cn/post-7805415-131365606-1.shtml
http://blog.tianya.cn/post-7805415-131365607-1.shtml
http://blog.tianya.cn/post-7805416-131365608-1.shtml
http://blog.tianya.cn/post-7805416-131365609-1.shtml
http://blog.tianya.cn/post-7805416-131365610-1.shtml
http://blog.tianya.cn/post-7805417-131365613-1.shtml
http://blog.tianya.cn/post-7805417-131365614-1.shtml
http://blog.tianya.cn/post-7805417-131365615-1.shtml
http://blog.tianya.cn/post-7805418-131365616-1.shtml
http://blog.tianya.cn/post-7805418-131365618-1.shtml
http://blog.tianya.cn/post-7805418-131365619-1.shtml
http://blog.tianya.cn/post-7805419-131365620-1.shtml
http://blog.tianya.cn/post-7805419-131365621-1.shtml
http://blog.tianya.cn/post-7805419-131365622-1.shtml
http://blog.tianya.cn/post-7805421-131365624-1.shtml
http://blog.tianya.cn/post-7805421-131365626-1.shtml

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值