Python Postgres排序已对大型数据库中的数据进行排序

Python Postgres排序已对大型数据库中的数据进行排序,python,postgresql,Python,Postgresql,我正在使用一个postgres 10数据库,其中包含数十亿行物联网数据(我们称之为主数据)。数据以一种结构存储:SENSOR_ID、TIMESTAMP、VALUE,其中我使用一个辅助表来获取关于传感器的元数据(让我们调用辅助表) 主表已按时间顺序(主键)存储。我访问python代码中的数据,对IOT环境进行一些模拟(使用这些信息检查流、模型、ext)。数据按时间顺序从数据库中出来是很重要的,因此为了保证这一点,我们的查询使用ORDERBYTIME子句 因为我们的计算机无法获取数十亿的回报,我们正

我正在使用一个postgres 10数据库,其中包含数十亿行物联网数据(我们称之为主数据)。数据以一种结构存储:SENSOR_ID、TIMESTAMP、VALUE,其中我使用一个辅助表来获取关于传感器的元数据(让我们调用辅助表)

主表已按时间顺序(主键)存储。我访问python代码中的数据,对IOT环境进行一些模拟(使用这些信息检查流、模型、ext)。数据按时间顺序从数据库中出来是很重要的,因此为了保证这一点,我们的查询使用ORDERBYTIME子句

因为我们的计算机无法获取数十亿的回报,我们正试图使用光标获取小批量的结果

我的问题是,对于“小”查询(比如100万),Postgres会识别出数据已经按排序顺序排列,只需快速扫描主索引(然后与元数据辅助表进行连接),而不会出现问题。如果我给它一个更大的查询,那么QEP将包含一个非常昂贵的排序操作,尽管数据不需要排序

有没有一种方法可以让优化器在使用光标时识别出数据已经处于有序状态并放弃排序

对于没有游标的较小查询,我们可以获得所需的性能和QEP,但对于较大的数据集来说,这很难实现

QEP的两个示例和优化器的一些奇怪问题。一个使用没有限制的查询,另一个使用高于行数的限制(或足够使其平凡化)

无限制条款:

EXPLAIN SELECT timestampmilli, value, id, globalid FROM data11 TB1,
sensor_enrichment_11 TS WHERE TB1.id = TS.globalid AND
timestampmilli BETWEEN '2018-01-01'::timestamp AND '2018-06-06'::timestamp
ORDER BY timestampmilli;
EXPLAIN SELECT timestampmilli, value, id, globalid FROM data11 TB1,
sensor_enrichment_11 TS WHERE TB1.id = TS.globalid AND
timestampmilli BETWEEN '2018-01-01'::timestamp AND '2018-06-06'::timestamp 
ORDER BY timestampmilli LIMIT 10000000;
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
限制(成本=0.99..82250110.69行=10000000宽=28)
->嵌套循环(成本=0.99..2076787807.52行=252496661宽度=28)
->在data11 tb1上使用data11_pkey进行索引扫描(成本=0.58..994786742.16行=252491094宽度=24)
索引条件:((时间戳>='2018-01-01 00:00:00'::不带时区的时间戳)和(时间戳索引仅使用传感器11上的传感器11进行扫描(成本=0.41..4.28行=1宽度=4)
索引条件:(globalid=tb1.id)

是什么让你认为数据在表中是严格有序的?是什么让你认为这是在加入后维护的?没有强制表始终保持排序的约束。但是,索引必须始终进行排序。如果查询使用索引,但仍然进行排序,这很奇怪。如果它放弃索引并使用表顺序扫描,然后必须排序。请显示有问题查询的计划。
EXPLAIN SELECT timestampmilli, value, id, globalid FROM data11 TB1,
sensor_enrichment_11 TS WHERE TB1.id = TS.globalid AND
timestampmilli BETWEEN '2018-01-01'::timestamp AND '2018-06-06'::timestamp 
ORDER BY timestampmilli LIMIT 10000000;
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.99..82250110.69 rows=10000000 width=28)
   ->  Nested Loop  (cost=0.99..2076787807.52 rows=252496661 width=28)
         ->  Index Scan using data11_pkey on data11 tb1  (cost=0.58..994786742.16 rows=252491094 width=24)
               Index Cond: ((timestampmilli >= '2018-01-01 00:00:00'::timestamp without time zone) AND (timestampmilli <= '2018-06-06 00:00:00'::timestamp without time zone))
         ->  Index Only Scan using sensor_enrichment_11_pkey on sensor_enrichment_11 ts  (cost=0.41..4.28 rows=1 width=4)
               Index Cond: (globalid = tb1.id)