zulip/zerver
Steve Howell 8cc82c6cbe Optimize /json/update_message_flags.
I added filter() statements to do_update_message_flags().

Here is some context:

Steve Howell: Case 1, have AND clause to reduce work for DB.

humbug=> update zerver_usermessage set flags = (flags & ~1) where id > 9000;
UPDATE 382
humbug=> select count(*) from zerver_usermessage where (flags & 1) = 0;
 count
-------
   382
(1 row)

humbug=> explain analyze update zerver_usermessage set flags = (flags | 1) where (flags & 1) = 0;
                                                       QUERY PLAN
------------------------------------------------------------------------------------------------------------------------
 Update on zerver_usermessage  (cost=0.00..266.85 rows=47 width=27) (actual time=5.727..5.727 rows=0 loops=1)
   ->  Seq Scan on zerver_usermessage  (cost=0.00..266.85 rows=47 width=27) (actual time=0.045..2.751 rows=382 loops=1)
         Filter: ((flags & 1::bigint) = 0)
         Rows Removed by Filter: 9000
 Total runtime: 5.759 ms
(5 rows)

humbug=> select count(*) from zerver_usermessage where (flags & 1) = 0;
 count
-------
     0
(1 row)
Leo Franchi: Sounds reasonable, but I know way less than zev about DBs so I'll defer to his judgement :)

Steve Howell: Case 2, how the code works now:

humbug=> update zerver_usermessage set flags = (flags & ~1) where id > 9000;
UPDATE 382
humbug=> select count(*) from zerver_usermessage where (flags & 1) = 0;
 count
-------
   382
(1 row)

humbug=> explain analyze update zerver_usermessage set flags = (flags | 1);
                                                        QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
 Update on zerver_usermessage  (cost=0.00..243.28 rows=9382 width=27) (actual time=362.075..362.075 rows=0 loops=1)
   ->  Seq Scan on zerver_usermessage  (cost=0.00..243.28 rows=9382 width=27) (actual time=0.008..6.138 rows=9382 loops=1)
 Total runtime: 362.105 ms
(3 rows)

humbug=> select count(*) from zerver_usermessage where (flags & 1) = 0;
 count
-------
     0
(1 row)
Steve Howell: In both trials, we set it up so that only 382 of 9382 rows need to be updated. The first trial runs about 63x as fast. The second trial, if my theory is correct, is doing 24x as many writes as it needs. Both trials are reading all 9382 rows.

Steve Howell: The expense of the update statement seems to be proportional to the number of rows you "update", not the number of rows that you actually change.

Steve Howell: For now I created #1869.

Zev Benjamin: That sounds like a reasonable explanation. The disk IO can be expensive

(imported from commit d9090daee1f81cad76c430de0956f9bd504da075)
2013-10-15 11:30:13 -04:00
..
fixtures Attempt to convert JIRA mentions to Zulip mentions 2013-10-07 13:59:36 -04:00
lib Optimize /json/update_message_flags. 2013-10-15 11:30:13 -04:00
management Queue the day 1 and day 2 Zulip followup emails 2013-10-10 19:32:21 -04:00
migrations [schema] Increase maximum stream name length to 60. 2013-10-15 09:13:35 -04:00
templatetags [manual] Rename Django app from zephyr to zerver. 2013-08-06 07:39:36 -04:00
tests/frontend Tweak alert_word matches and add some more tests 2013-10-10 10:58:21 -04:00
views [schema] Increase maximum stream name length to 60. 2013-10-15 09:13:35 -04:00
worker Queue the day 1 and day 2 Zulip followup emails 2013-10-10 19:32:21 -04:00
__init__.py [manual] Rename Django app from zephyr to zerver. 2013-08-06 07:39:36 -04:00
context_processors.py [manual] Rename Django app from zephyr to zerver. 2013-08-06 07:39:36 -04:00
decorator.py Add Mandrill decorators, credentials, actions 2013-10-10 19:32:21 -04:00
exceptions.py [manual] Rename Django app from zephyr to zerver. 2013-08-06 07:39:36 -04:00
filters.py Change Humbug => Zulip in name of exception filter module. 2013-08-07 10:00:07 -04:00
finders.py Change Humbug => Zulip in name of finder module. 2013-08-07 10:00:07 -04:00
forms.py Allow MIT to invite coworkers. 2013-09-19 17:14:41 -04:00
handlers.py Change Humbug => Zulip in names of error reporting handlers. 2013-08-07 10:00:07 -04:00
middleware.py Clean up slow log displays 2013-10-02 11:26:58 -04:00
models.py [schema] Increase maximum stream name length to 60. 2013-10-15 09:13:35 -04:00
openid.py [manual] Rename Django app from zephyr to zerver. 2013-08-06 07:39:36 -04:00
retention_policy.py [manual] Rename Django app from zephyr to zerver. 2013-08-06 07:39:36 -04:00
static_header.txt Change Humbug => Zulip in text/comments. 2013-08-07 10:00:07 -04:00
storage.py Change Humbug => Zulip in name of storage module. 2013-08-07 10:00:07 -04:00
tests.py Fix test to check for new 60-char stream name length limit 2013-10-15 10:24:07 -04:00
tornado_callbacks.py Don't cache UserPresence info. 2013-09-17 14:51:56 -04:00
tornadoviews.py Let clients specify how long queues shall live, within limits 2013-08-20 16:19:07 -04:00