Sql 优化一个大的;独特的;在postgres中选择

Sql 优化一个大的;独特的;在postgres中选择,sql,postgresql,Sql,Postgresql,我有一个相当大的数据集(数百万行)。我在将“独特”概念引入某个查询时遇到问题。(我将distinct放在引号中,因为这可以由posgtres关键字distinct或“groupby”表单提供) 非区分搜索需要1ms-2ms;所有引入“独特”概念的尝试都将其扩展到50000ms-90000ms范围 我的目标是根据最新资源在事件流中的出现情况显示它们 我的非独立查询本质上是这样的: SELECT resource.id AS resource_id, stream_event.eve

我有一个相当大的数据集(数百万行)。我在将“独特”概念引入某个查询时遇到问题。(我将distinct放在引号中,因为这可以由posgtres关键字distinct或“groupby”表单提供)

非区分搜索需要1ms-2ms;所有引入“独特”概念的尝试都将其扩展到50000ms-90000ms范围

我的目标是根据最新资源在事件流中的出现情况显示它们

我的非独立查询本质上是这样的:

SELECT
    resource.id AS resource_id,
    stream_event.event_timestamp AS event_timestamp
FROM
    resource
    JOIN
        resource_2_stream_event ON (resource.id = resource_2_stream_event.resource_id)
    JOIN
        stream_event ON (resource_2_stream_event.stream_event_id = stream_event.id)
WHERE
    stream_event.viewer = 47
ORDER BY event_timestamp DESC
LIMIT 25
;
我尝试了使用DISTINCT、GROUPBY和MAX(事件\时间戳)的多种不同形式的查询(和子查询)。问题不是得到一个有效的查询,而是得到一个在合理的执行时间内有效的查询。查看每一个的解释分析输出,所有内容都在运行索引。问题似乎是,任何重复数据消除的尝试都必须将整个结果集组装到磁盘上;由于每个表都有数百万行,这就成为了瓶颈

--

更新

以下是一个查询工作组:

EXPLAIN ANALYZE 
SELECT
    resource.id AS resource_id,
    max(stream_event.event_timestamp) AS stream_event_event_timestamp
FROM 
    resource 
    JOIN resource_2_stream_event ON (resource_2_stream_event.resource_id = resource.id) 
    JOIN stream_event ON stream_event.id = resource_2_stream_event.stream_event_id
WHERE (
        (stream_event.viewer_id = 57) AND 
        (resource.condition_1 IS NOT True) AND 
        (resource.condition_2 IS NOT True) AND 
        (resource.condition_3 IS NOT True) AND 
        (resource.condition_4 IS NOT True) AND 
        ( 
            (resource.condition_5 IS NULL) OR (resource.condition_6 IS NULL) 
        )
    )
GROUP BY (resource.id)
ORDER BY stream_event_event_timestamp DESC LIMIT 25;
查看查询计划器(通过EXPLAIN ANALYZE),添加max+groupby子句(或distinct)似乎会强制进行顺序扫描。这花费了大约一半的计算机时间。已经有一个包含每个“条件”的索引,我尝试创建一组索引(每个元素一个)。没用


在任何情况下,差异都在2ms和72000ms之间。通常,
上的distinct on
是每件事获得一行的最有效方法。我建议尝试:

SELECT DISTINCT ON (r.id) r.id AS resource_id, se.event_timestamp
FROM resource r JOIN
     resource_2_stream_event r2se
     ON r.id = r2se.resource_id JOIN
     stream_event se
     ON r2se.stream_event_id = se.id
WHERE se.viewer = 47
ORDER BY r.id, se.event_timestamp DESC
LIMIT 25;
资源(id、事件\u时间戳)
上的索引可能有助于提高性能

编辑:

您可以尝试使用CTE获得您想要的:

WITH CTE as (
      SELECT r.id AS resource_id,
             se.event_timestamp AS stream_event_event_timestamp
      FROM resource r JOIN
           resource_2_stream_event r2se
           ON r2se.resource_id = r.id JOIN
           stream_event se
           ON se.id = r2se.stream_event_id
      WHERE ((se.viewer_id = 57) AND 
             (r.condition_1 IS NOT True) AND 
             (r.condition_2 IS NOT True) AND 
             (r.condition_3 IS NOT True) AND 
             (r.condition_4 IS NOT True) AND 
             ( (r.condition_5 IS NULL) OR (r.condition_6 IS NULL) 
             )
            )
    )
SELECT resource_id, max(stream_event_event_timestamp) as stream_event_event_timestamp
FROM CTE
GROUP BY resource_id
ORDER BY stream_event_event_timestamp DESC
LIMIT 25;

Postgres实现了CTE。因此,如果没有那么多匹配项,这可能会通过使用CTE的索引来加快查询速度。

您能否添加一个完整版本的工作查询以获得所需的结果。此外,如果几个变体给出相同的结果,则显示它们。还有,这些WHERE/ORDER BY和LIMIT 25有多重要?发布said
EXPLAIN analysis
怎么样?下面提到的独特查询的完整代码看起来如何?您能提供示例数据吗?或者设置SQLFIDLE吗?0)查询的意图1)表定义,包括索引2)结果查询计划3)相关配置设置。也许您可以使用CTE实现“fast”然后再执行其他操作。我需要按最新的事件\u时间戳排序,因此在使用distinct时需要使用嵌套子查询。我需要的选择是
EXPLAIN ANALYZE select sq.*FROM(DISTINCT_QUERY)sq ORDER BY sq.event_timestamp DESC LIMIT 25
,其中
DISTINCT\u QUERY
是您的查询。它的运行速度比另一个select略快(介于1%和4%之间),但仍然太长。从
ORDER
子句中删除
r.id
而不降级到子查询是否有效?谢谢您的帮助!这绝对是达到目的!降到20多岁。(仅供参考,
max
需要从子查询中删除)。我们将继续玩CTE。下一个想法是在CTE中添加类似于
order by stream\u event\u timestamp desc limit 1000
的内容,并希望您在该列表中至少有25个资源ID。我在CTE之外迁移join+where on
r
时获得了不错的性能提升。它把我带到了4s-7s。范围我仍然需要在500毫秒以下,但这是一个提升。