Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 按不同表中的列高效排序_Sql_Postgresql - Fatal编程技术网

Sql 按不同表中的列高效排序

Sql 按不同表中的列高效排序,sql,postgresql,Sql,Postgresql,我们目前正在尝试改进一个系统,该系统允许用户按未显示的字段对大于100k的大型对象列表进行筛选和排序。由于字段可以动态选择,我们计划也动态地构建查询 这听起来不太难,基础工作也很容易完成,但问题在于数据的结构。在某些情况下,可能需要一些成本较高或较低的联接,这可能会导致相当昂贵的查询,尤其是当这些联接组合在一起时,即从表中选择*联接一些昂贵的联接另一个昂贵的联接 过滤不是什么大问题,因为我们可以使用交叉点 然而,排序需要我们首先构建一个包含所有必要数据的表,如果通过一个包含所有这些连接的大型se

我们目前正在尝试改进一个系统,该系统允许用户按未显示的字段对大于100k的大型对象列表进行筛选和排序。由于字段可以动态选择,我们计划也动态地构建查询

这听起来不太难,基础工作也很容易完成,但问题在于数据的结构。在某些情况下,可能需要一些成本较高或较低的联接,这可能会导致相当昂贵的查询,尤其是当这些联接组合在一起时,即从表中选择*联接一些昂贵的联接另一个昂贵的联接

过滤不是什么大问题,因为我们可以使用交叉点

然而,排序需要我们首先构建一个包含所有必要数据的表,如果通过一个包含所有这些连接的大型select语句来完成,那么这将变得非常昂贵

所以问题是:有没有更有效的方法

我可以这样想:

对第一列执行select查询并按该列排序 对于基本上具有相同顺序(例如相同值)的所有元素,请执行另一个查询以解决该问题 重复上述步骤,直到顺序明确无误,或者我们没有排序标准
这有意义吗?如果是的话,如何在Postgresql 9.4中做到这一点?我们目前无法升级9.5+解决方案,尽管welcome目前没有帮助。

这有帮助吗,还是太微不足道了?子查询可以是预制连接视图


这只是一条经验法则,但通常在一个查询中执行所有操作都是最有效的,即选择。。。从选择。。从…起参加相交选择。。。q订购人。。。。在这样的设置中,最大的问题通常是防止人们使用太少的限制性条件,这会导致执行时间和结果集爆炸。您是否不可避免地在最后对庞大的集合进行排序?。。是按原始列还是按预排序列和?但任何基于较小订单建立订单的方式都需要整套订单。对不起,如果我建议的是无意义的-我只是不明白如果你需要订购的话,你怎么能避免大的排序。。。但问题在于数据的结构。。。它是如何构造的?@LaurenzAlbe实际上我们的方法是这样的,即选择。。。从使用交叉点的筛选查询中,连接排序依据所需的任何内容-问题的目的是如何优化该连接排序部分所需的任何内容。@VaoTsun理想情况下,我们可以仅使用一列或最多使用两列对整个预筛选集进行排序,假设我们按价格和名称对产品进行排序。因此,如果一列已经产生了一个明确的顺序,我们就不必添加任何额外的连接或执行其他不会改变结果的可能昂贵的查询。-希望这是有道理的我也有同样的想法,但是——在pg_catalog联接上,这样的三重排序比是74毫秒,而在子查询中没有排序比是73毫秒,但只是按原始列排序,我不知道排名,但这似乎是一种至少减少需要移动的数据的方法。谢谢你。
SELECT t0.id, t0.a,t0.b,t0.c, ...
FROM main_table t0
JOIN ( SELECT t1.id AS id
        , rank() OVER (ORDER BY whatever) AS rnk
        FROM different_tables_or_JOINS
        ) AS t1 ON t1.id=t0.id

JOIN ( SELECT t2.id AS id
        , rank() OVER (ORDER BY whatever) AS rnk
        FROM different_tables_or_JOINS2
        ) AS t2 ON t2.id=t0.id

        ...

ORDER BY t1.rnk
        , t2.rnk
        ...
        , t0.id
        ;