This query shows up in the slow query logs on a site I'm working on:

Count         : 1.96k  (2.40%)
Time          : 3984 s total, 2.029547 s avg, 2 s to 3 s max  (1.57%)
  95% of Time : 3728 s total, 2 s avg, 2 s to 2 s max
Lock Time (s) : 0 total, 0 avg, 0 to 0 max  (0.00%)
  95% of Lock : 0 total, 0 avg, 0 to 0 max
Rows sent     : 0 avg, 0 to 0 max  (0.00%)
Rows examined : 543.05k avg, 537.20k to 548.72k max  (2.19%)
Database      : 
Users         : 
  connect@prod1 172.16.100.162 : 100.00% (1963) of query, 99.85% (81732) of all users

Query abstract:
SELECT txn_id, uid, points, time_stamp, operation, description FROM userpoints_txn WHERE status = N AND expired = N AND (expirydate < N AND expirydate != N);

Query sample:
SELECT txn_id, uid, points, time_stamp, operation, description 
          FROM userpoints_txn 
          WHERE status = 0 AND expired = 0 
          AND (expirydate < 1289600109 AND expirydate != 0);

MariaDB [connect]> EXPLAIN SELECT txn_id, uid, points, time_stamp, operation, description FROM userpoints_txn WHERE status = 0 AND expired = 0 AND (expirydate < 1289600109 AND expirydate != 0);
+----+-------------+----------------+------+---------------+--------+---------+-------+--------+-------------+
| id | select_type | table          | type | possible_keys | key    | key_len | ref   | rows   | Extra       |
+----+-------------+----------------+------+---------------+--------+---------+-------+--------+-------------+
|  1 | SIMPLE      | userpoints_txn | ref  | status        | status | 4       | const | 249584 | Using where |
+----+-------------+----------------+------+---------------+--------+---------+-------+--------+-------------+
1 row in set (0.00 sec)

I added an index like such:

ALTER TABLE userpoints_txn ADD INDEX (status, expired, expirydate);

With that index I get:

MariaDB [connect]> EXPLAIN SELECT txn_id, uid, points, time_stamp, operation, description FROM userpoints_txn WHERE status = 0 AND expired = 0 AND (expirydate < 1289600109 AND expirydate != 0);
+----+-------------+----------------+-------+-----------------+----------+---------+------+------+-------------+
| id | select_type | table          | type  | possible_keys   | key      | key_len | ref  | rows | Extra       |
+----+-------------+----------------+-------+-----------------+----------+---------+------+------+-------------+
|  1 | SIMPLE      | userpoints_txn | range | status,status_2 | status_2 | 10      | NULL |   20 | Using where |
+----+-------------+----------------+-------+-----------------+----------+---------+------+------+-------------+
1 row in set (0.00 sec)

So 20 rows vs. 249k.

Here's a patch.

Comments

Status: Needs review » Needs work

The last submitted patch, userpoints_slow_query.patch, failed testing.

berdir’s picture

+++ userpoints.install	(working copy)
@@ -271,3 +272,12 @@
+  db_add_index(&$ret, 'userpoints_txn', 'expire', array('status', 'expired', 'expirydate'));

I think the & is wrong here :)

Oh, and ignore the test results, 6.x-1.x tests don't pass right now.

Powered by Dreditor.

catch’s picture

Status: Needs work » Needs review
StatusFileSize
new739 bytes

You mean 'call time pass by reference is deprecated' ;) grr, can't believe I did that.

Updated patch, back to CNR.

Status: Needs review » Needs work

The last submitted patch, userpoints_slow_query-983950.patch, failed testing.

catch’s picture

Status: Needs work » Needs review

Ignoring the bot.

kbahey’s picture

Status: Needs review » Patch (to be ported)

Thanks Nat.

Committed to 6.x

Berdir, does this need to be ported to 7.x?

berdir’s picture

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

Only the definition in hook_schema needs to be updated for new installations. I'll do that myself, no re-roll necessary...

catch’s picture

Thanks!

berdir’s picture

Status: Patch (to be ported) » Fixed

Commited to 7.x-1.x.

berdir’s picture

Status: Fixed » Closed (duplicate)