我有两个索引表:
- latest_channel_snapshots_views_idx (view_count DESC NULLS LAST)
- latest_channel_snapshots_network_views_idx (network_id, view_count DESC NULLS LAST)
我想要的是能够按整体和特定网络内的 view_count 进行排序。Postgres 对这两种情况都使用正确的索引。但是,如果我想查找 network_id 为 NULL 的大多数视图的记录,它会使用第一个索引,并过滤掉 ,因此执行速度非常慢:
explain analyze SELECT *
FROM latest_channel_snapshots
WHERE network_id IS NULL
ORDER BY view_count DESC NULLS LAST
LIMIT 5 OFFSET 500000;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=39599.04..39599.44 rows=5 width=74) (actual time=1926.271..1926.287 rows=5 loops=1)
-> Index Scan using latest_channel_snapshots_views_idx on latest_channel_snapshots (cost=0.00..42001.59 rows=530336 width=74) (actual time=0.060..1899.224 rows=500005 loops=1)
Filter: (network_id IS NULL)
Rows Removed by Filter: 305022
Total runtime: 1926.309 ms
(5 rows)
你在这里有两个问题:
大偏移量:PG 将需要扫描提供的偏移量行数,并且更喜欢在表扫描之上使用索引来执行此操作。
如何索引数据:我认为部分索引可能对您有所帮助。你能试一下吗
在 latest_channel_snapshots(view_count DESC NULLS LAST) 上创建索引 xxx_idx,其中 network_id 为空;
有关部分索引的更多信息,请参见http://www.postgresql.org/docs/9.2/static/indexes-partial.html。特别是,关于未开票订单的示例 11-2 似乎适用于您的情况。