Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.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
PostgreSQL:保留排序顺序/临时索引/分页_Sql_Postgresql_Pagination - Fatal编程技术网

PostgreSQL:保留排序顺序/临时索引/分页

PostgreSQL:保留排序顺序/临时索引/分页,sql,postgresql,pagination,Sql,Postgresql,Pagination,我正在使用PostgreSQL,我打算使用分页。目标表包含1M+行。原则上,这是直截了当的 SELECT * FROM myTable ORDER BY orderCol LIMIT <pageSize> OFFSET <offset>; 从myTable ORDER BY orderCol LIMIT OFFSET中选择*; 现在,当orderCol被索引时,速度很快,但是当orderCol没有索引时,速度会慢一个数量级。显然,在最坏的情况下,dbms被迫执行全表扫

我正在使用PostgreSQL,我打算使用分页。目标表包含1M+行。原则上,这是直截了当的

SELECT * FROM myTable ORDER BY orderCol LIMIT <pageSize> OFFSET <offset>;
从myTable ORDER BY orderCol LIMIT OFFSET中选择*;
现在,当orderCol被索引时,速度很快,但是当orderCol没有索引时,速度会慢一个数量级。显然,在最坏的情况下,dbms被迫执行全表扫描,并且必须对请求的每个页面的数据进行排序

[Edit:更具体地说,
orderCol
可能会更改,即在运行时确定。]

[Edit2:索引
orderCol
提高排序性能的一般假设似乎是错误的。如果我在
orderCol
中添加索引,查询时间将增加约70%。]

一个显而易见的解决方案是在必要时创建一个带有适当索引的临时表,并用适当的数据填充该表(…我认为)。但这会复制所有数据

有没有办法在请求之间“保留”排序顺序?还是创建一个临时索引


非常感谢您提前给出答案。

是什么阻止了您为本专栏编制索引

我有一个类似的问题,但是对于一个20GB/40M+行的表,有很多“where”条件。数据是静态的,因此我让DW服务器运行一个每日脚本,该脚本只提取相关数据并创建一个150k表

更新

编辑:更具体地说,orderCol可能会更改,即在运行时确定

您的意思是,每次有人运行查询时,order列中的值都会更改(或者该列可以不同,如column1、colume2等)

查看物化视图

您可以在此查询上创建一个视图,然后从此视图运行所有查询(并通过脚本每隔x分钟/小时/天删除一次查询)。比临时表更容易处理


除此之外,还有一些技巧取决于详细的用例,但没有现成的解决方案

好的,这里是我提出的一个解决方案

问题实际上是确定性行寻址和关系模型不兼容。我基本上想做的是告诉数据库下一步要去哪里。但是,由于请求彼此独立,并且我们不能对表的物理结构做出任何假设,所以处理行的唯一方法是使用唯一的列值

因此,以下解决方案:

CREATE TEMPORARY TABLE orderTable( id int, rank int );
CREATE INDEX orderIdx ON orderTable( rank );
INSERT INTO orderTable (
  select id, row_number() over (order by orderCol) as rank 
  from myTable ORDER BY orderCol
);
现在,我可以获取如下页面:

SELECT myTable.id, orderCol 
FROM myTable JOIN orderTable ON myTable.id=orderTable.id 
WHERE rank >= <lower> AND rank <= <upper>;
选择myTable.id,orderCol
从myTable连接myTable.id=orderTable.id上的orderTable

其中rank>=和rank您遇到了几个问题:

是的,对未编制索引的列进行排序很慢 您可能真的想要索引所有可排序的列配置,至少是那些经常按应用程序排序的配置。在这个问题上有一些有趣的见解

偏移速度慢 即使有索引,跳转到高页码也很慢,因为您必须遍历整个索引才能进行
偏移量
计数。试着看看你是否可以用这个来代替

seek方法实质上跳到上一页最后一条记录之后的第一条记录,例如

SELECT * 
FROM myTable 
WHERE orderCol > :lastValueforOrderCol
ORDER BY orderCol
LIMIT <pageSize>;
选择*
从myTable
其中orderCol>:orderCol的最后一个值
按订单订购
限制;
现在,您不再按偏移量访问记录,而是通过使用谓词,对所有符合条件的
ordercol
进行索引是必不可少的

注意,此方法不允许跳转到固定的顺序位置,如
偏移量
。它的行为更像是推特懒散地加载“后续推文”。这可能是可取的,也可能不是可取的

注意,“seek方法”也被调用

全表扫描可能比索引扫描快 由于您没有任何谓词,因此执行哑全表扫描并在内存中执行排序可能会更快,而不是加载所有索引b树节点(可能分散在磁盘上)以跳过行。一旦添加了选择性谓词,这种观察结果可能会发生逆转


不过,令我惊讶的是,PostgreSQL的Optimizer不会自动选择全表扫描。

只需等到遇到“偏移量100000”问题。所有数据库的高偏移量性能都很差,甚至像Lucene这样的搜索数据库也是如此。这是计算中尚未解决的问题之一。我使用主键作为排序键,在一个有1M个条目的表上执行了这样的测试。偏移量大与否没有多大区别。
orderCol
可能会更改您的意思是它是传递给查询的参数吗?是的。正在排序的列是应用程序定义的参数。@FuzzyChef:这个问题可以通过以下方法解决:不幸的是,索引和集群没有多大帮助。原因是,除非要排序的列只包含唯一的值,否则dbms仍然需要对所有数据进行排序,以便找出排序集中第x个条目的位置。@dsd,更大的问题是排序的列可能会更改。PostgreSQL可以使用索引通过顺序和限制检索表的一小部分,但在您的情况下,这可能意味着索引太多。Eek,每个排序列一个表!:-)如果添加谓词呢?这将使每列和谓词有一个表!你听说过这家公司吗?它允许在固定时间内分页。。。