postgresql - 加快代价高昂的连接操作 - 大表和小表
问题描述
我正在使用 Postgres 存储大量事务并尝试将特定 Select 语句的读取时间保持在数十毫秒内。
TableA 的架构(> 100mm 行):(userID int,itemID int)。由用户 ID 索引
TableB 的架构(1mm 行):(categoryID int,itemID int)。按类别 ID 索引。类别数 = 500,每个 itemID 只属于一个类别。
我要优化的查询目前需要大约 100 毫秒才能执行是:
select * from TableA
where userID = x and itemID in
(select itemID from TableB
where categoryID = y)
解决此问题的一种简单方法是创建一个非规范化表,其中 userID、itemID 和 categoryID 作为列并在 (userID, categoryID) 上建立索引。但是,categoryID -> itemID 映射可能会发生变化,因此我希望避免对表进行全面扫描并在每次发生这种情况时更新行。
有没有其他技术/索引方法来加速这个 JOIN 操作?任何安排数据的替代方式也将不胜感激。谢谢!
编辑:添加示例查询计划。
[(' -> Hash Semi Join (cost=159.50..382.67 rows=164 width=50)'),
(' Hash Cond: (tableA.itemId = tableB.itemId)'),
(' -> Index Scan using userId on tableA (cost=0.57..208.31 rows=5185 width=50)'),
(' Index Cond: (userId = 4000)'),
(' -> Hash (cost=117.05..117.05 rows=3350 width=4)'),
(' Buckets: 4096 Batches: 1 Memory Usage: 161kB',),
(' -> Index Scan using categoryId on tableB (cost=0.42..117.05 rows=3350 width=4)'),
(' Index Cond: (categoryId = 1002)',), ('Planning time: 0.149 ms',)]
解决方案
也许 Exists 在这里会有所帮助: EXISTS 和 IN 之间的区别
对于您的查询:
Select * from TableA a
Where userID = x
and exists (Select itemId from TableB b where categoryID = y and a.itemId = b.itemId)
推荐阅读
- python - 如何在具有不同条件的列表上迭代两次?
- python - 有没有办法在 python tkinter 中部署我的 ML 模型
- python - python中的自定义帮助单击
- javascript - 在完全加载 DOM 内容之前渲染 VueJS 事件处理程序?
- mysql - 当我们在数据库中使用 json 数据类型时?
- excel - 出现错误 91 - 对象变量或未设置块变量
- excel - 为什么此 VBA 代码不对我的 Excel 工作表进行任何更改?
- javascript - JS 为数独后援者添加延迟
- python - awk 比较 2 个未排序文件中的 2 列,并在匹配后返回第 2 个文件中的特定列
- ajax - Shopify 预测搜索 Ajax 调用