messaging_cron() runs the following query:

DELETE FROM {messaging_store} WHERE log = 1 AND queue = 0 AND sent < %d', time() - $expire);

There's only an index on log, so this does almost a full table scan - with 350k rows, on the database I'm looking at it had to examine over 200k rows even when only 135k would be returned:

mysql> SELECT COUNT(*) FROM messaging_store WHERE log = 1 AND queue = 0 AND sent < 1295936089;
+----------+
| COUNT(*) |
+----------+
|   135526 | 
+----------+
1 row in set (0.89 sec)

mysql> EXPLAIN SELECT COUNT(*) FROM messaging_store WHERE log = 1 AND queue = 0 AND sent < 1295936089;
+----+-------------+-----------------+------+---------------+------+---------+-------+--------+-------------+
| id | select_type | table           | type | possible_keys | key  | key_len | ref   | rows   | Extra       |
+----+-------------+-----------------+------+---------------+------+---------+-------+--------+-------------+
|  1 | SIMPLE      | messaging_store | ref  | queue,log     | log  | 1       | const | 218314 | Using where | 
+----+-------------+-----------------+------+---------------+------+---------+-------+--------+-------------+
1 row in set (0.00 sec)

Attached patch is for the DRUPAL-6--4 branch, drops the log index, and adds log_queue_sent.

Would be good to get it into the DRUPAL-6--2 branch as well, but that seems tricky given update numbering.

Also the DRUPAL-6--4 branch has new queries here, for example:

db_query('DELETE FROM {' . self::DB_TABLE . '} WHERE log = 1 AND queue = 0 AND sent < %d OR error = 1 AND created < %d', $time, $time);

However the indexes don't appear to have been updated for these new queries either.

CommentFileSizeAuthor
messaging_indexes.patch1.05 KBcatch

Comments

danepowell’s picture

Version: 7.x-1.x-dev » 6.x-4.x-dev

Seems like you posted to the wrong branch.