我正在查询一个包含两种skuID的约4M数据的表,并使用order by on version,因为对于一个skuID,有大约5k个版本的数据,并使用limit获取最高版本。
查询:
select * FROM table rb
WHERE rb.sku_id='' or rb.package_sku_id=''
order by version desc
limit 1;
通过对查询使用explain,我们发现ORDER BY和LIMIT占用了查询的大部分成本:
Limit (cost=0.43..5304.64 rows=1 width=861) (actual time=50327.036..50327.041 rows=1 loops=1)
Buffers: shared hit=361280 read=104302 written=18
I/O Timings: read=40363.693 write=0.215
-> Index Scan Backward using "IDX488yr43nr28a1yml9lb5i7jfv" on referral_benefits rb (cost=0.43..9552890.48 rows=1801 width=861) (actual time=50327.028..50327.028 rows=1 loops=1)
Filter: (((sku_id)::text = 'b1d5fa77-fda8-466c-b8b0-a8e60d1f78a5'::text) OR ((package_sku_id)::text = 'b1d5fa77-fda8-466c-b8b0-a8e60d1f78a5'::text))
Rows Removed by Filter: 1361027
Buffers: shared hit=361280 read=104302 written=18
I/O Timings: read=40363.693 write=0.215
Planning Time: 1.121 ms
Execution Time: 50329.843 ms
我们已经在skuId和package_sku_id上添加了索引,但这并没有减少时间。
在这方面需要指导。先谢谢你了
2条答案
按热度按时间myzjeezk1#
如果你有两个索引,一个在
(sku_id, version)
上,一个在(package_sku_id, version)
上,那么你可以通过执行以下操作来获得非常快的执行速度:但请注意,如果将LIMIT增加到1以上,则如果同一行满足两个SKU条件,则此查询可能会返回重复的行。
txu3uszq2#
PostgreSQL提供了部分索引,即只应用于表的子集的索引。请使用该索引类型,并使其仅包含要查看行。然后DBMS只需要读取该索引,数据就会排序出来:
另一个选项是只包含所需顶行的单独表。编写一个触发器来保持更新。