首页 文章

Postgres中的并发查询

提问于
浏览
3

我会尽快描述一下我必须理解这个问题的目的 . 我有用Java开发的大型多线程应用程序 . 每个线程都有硬逻辑来加载,验证和解析文件,然后将这些数据插入数据库 . 也在线程中插入/更新数据库的阶段 . 每个线程运行几个存储过程,更新一个表 . 这些存储过程是每个线程的几个 .

该数据库同时由Web应用程序使用 . 所以你知道我遇到了死锁的问题 . 我尝试了所有的锁模型,但其中任何一个都没有帮助我 . 在某些时间段内,来自网络的SELECT工作时间很长 .

毕竟我的问题是什么?有postgres机制/手段来同步存储过程或查询?我知道它必须通过锁模型来完成,但我没有成功 . 作为MS Server的解决方案,我对SELECT语句使用“WITH NOLOCK” . 我可以通过代码同步来解决这个问题,但这是非常复杂的逻辑 .

根据请求,我在更新过程中发布慢查询的示例 .

SELECT c.id AS id,cn.name as name,c.parent_category_id AS parent_category_id,
        CASE WHEN EXISTS (
  SELECT p.id FROM category AS subcat
  INNER JOIN product AS p ON subcat.id = p.category_id
  WHERE subcat.parent_category_id=c.id LIMIT 1)
 THEN true ELSE false END AS autoupdate
        FROM category AS c
        INNER JOIN category_name AS cn ON c.id=cn.category_id
        LEFT JOIN category AS subcat ON subcat.parent_category_id = c.id
        WHERE c.parent_category_id=0AND cn.langid=1 AND c.id != 1
        AND EXISTS
            (SELECT p.id FROM product AS p
            WHERE p.category_id = c.id OR p.category_id = subcat.id LIMIT 1)
        GROUP BY c.sort,c.id,cn.name,c.parent_category_id
        ORDER BY c.sort, cn.name`

并解释:

'Group  (cost=947.74..987.96 rows=15 width=40)'
'  ->  Sort  (cost=947.74..947.75 rows=15 width=40)'
'        Sort Key: c.sort, cn.name, c.id, c.parent_category_id'
'        ->  Merge Left Join  (cost=125.84..947.62 rows=15 width=40)'
'              Merge Cond: (c.id = subcat.parent_category_id)'
'              Filter: (SubPlan 2)'
'              ->  Sort  (cost=64.46..64.46 rows=3 width=40)'
'                    Sort Key: c.id'
'                    ->  Nested Loop  (cost=0.00..64.45 rows=3 width=40)'
'                          ->  Seq Scan on category c  (cost=0.00..41.69 rows=3 width=18)'
'                                Filter: ((id  1) AND (parent_category_id = 0))'
'                          ->  Index Scan using category_name_category_id_langid on category_name cn  (cost=0.00..7.56 rows=1 width=30)'
'                                Index Cond: ((cn.category_id = c.id) AND (cn.langid = 1))'
'              ->  Sort  (cost=61.38..62.46 rows=1084 width=16)'
'                    Sort Key: subcat.parent_category_id'
'                    ->  Seq Scan on category subcat  (cost=0.00..39.52 rows=1084 width=16)'
'              SubPlan 2'
'                ->  Limit  (cost=0.00..27.29 rows=1 width=8)'
'                      ->  Seq Scan on product p  (cost=0.00..36459.98 rows=1336 width=8)'
'                            Filter: ((category_id = $0) OR (category_id = $1))'
'  SubPlan 1'
'    ->  Limit  (cost=0.00..2.68 rows=1 width=8)'
'          ->  Nested Loop  (cost=0.00..17889.28 rows=6684 width=8)'
'                ->  Seq Scan on category subcat  (cost=0.00..40.60 rows=10 width=8)'
'                      Filter: (parent_category_id = $0)'
'                ->  Index Scan using product_category_id on product p  (cost=0.00..1764.16 rows=668 width=16)'
'                      Index Cond: (p.category_id = subcat.id)'

谢谢!最好的问候Artem

2 回答

  • 2

    我认为你要找的术语是“isolation level” . 我想你的应用程序的某些部分可能会容忍脏读,不可重写的读取或幻像读取 . 但在当前版本的PostgreSQL中,writers don't block readers, and readers don't block writers .

    所以我的问题是:你怎么知道延迟是由锁定造成的,而不是由磁盘I / O,连接负载,其他进程(与dbms无关的进程,如长期运行的cron作业)引起的, 或者是其他东西?

  • 4

    PostgreSQL中不需要“WITH NOLOCK”,因为读者永远不会被作者阻止 . 阻止表上的SELECT的唯一方法是使用独占访问手动锁定表 - 这不是普通DML语句所做的事情 . 只有ALTER TABLE才能获得这样的锁 .

    但我不确定我是否明白你的问题 .

    你有死锁的问题吗?或者你认为没有测试你会拥有它们吗?

相关问题