Re: App very unresponsive while performing simple update

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Brendan Duddridge <brendan@xxxxxxxxxxxxxx> writes:

> We do have foreign keys on other tables that reference the product  table.
> Also, there will be updates going on at the same time as this  update. When
> anyone clicks on a product details link, we issue an  update statement to
> increment the click_count on the product. e.g.  update product set click_count
> = click_count + 1;

You should realize this will produce a lot of garbage records and mean you'll
have to be running vacuum very frequently. You might consider instead of
updating the main table inserting into a separate clickstream table. That
trades off not getting instantaneous live totals with isolating the
maintenance headache in a single place. That table will grow large but you can
prune it at your leisure without impacting query performance on your main
tables.

> There are 1.2 million rows in this table and my update will affect 200,000
> of them.
> 
> We do have indexes on all foreign keys that reference the product table.

Well I suppose you had an update running concurrently against one of CATEGORY,
MANUFACTURER, or MEDIA. Do any of those tables have a reference back to the
product table? Is it possible to have a record with a reference back to the
same record that refers to it?

I think you're seeing the problem because these foreign keys are all initially
deferred. That means you can update both tables and then can't commit either
one because it needs to obtain a shared lock on the other record which is
already locked for the update.

I'm not certain that making them not deferred would actually eliminate the
deadlock. It might just make it less likely. 

The deferred foreign key checks may also be related to the performance
complaints. In my experience they're quite fast but I wonder what happens when
you do a large batch update and then need to perform a whole slew of deferred
foreign key checks.

More likely you were blocking on some lock. Until that other query holding
that lock tries to commit Postgres won't actually detect a deadlock, it'll
just sit waiting until the lock becomes available.

Also, you have a lot of indexes here. That alone will make updates pretty
slow.

-- 
greg



[Postgresql General]     [Postgresql PHP]     [PHP Users]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Yosemite]

  Powered by Linux