Page MenuHomePhabricator

Block::load doesn't use an index.
Closed, ResolvedPublic

Description

Author: bugzilla_wikipedia_org.to.jamesd

Description:
The current block query from Block::load is:

mysql> explain select * from ipblocks where
(ipb_address='83.24.12.97' or ipb_user=73855);
+----------+------+----------------------+------+---------+--
----+------+-------------+

tabletypepossible_keyskeykey_len

ref | rows | Extra |
+----------+------+----------------------+------+---------+--
----+------+-------------+

ipblocksALLipb_address,ipb_userNULLNULL

NULL | 731 | Using where |
+----------+------+----------------------+------+---------+--
----+------+-------------+

Note that it's doing a full table scan - no index use.
Change to this:

explain select * from ipblocks where
ipb_address='83.24.12.97' union select * from ipblocks where
ipb_user=73855;
+----------+------+---------------+-------------+---------+--
-----+------+-------------+

tabletypepossible_keyskeykey_len

ref | rows | Extra |
+----------+------+---------------+-------------+---------+--
-----+------+-------------+

ipblocksrefipb_addressipb_address40

const | 1 | Using where |

ipblocksrefipb_useripb_user4

const | 1 | Using where |
+----------+------+---------------+-------------+---------+--
-----+------+-------------+

Two parts with a union, so each part can use an index.


Version: 1.4.x
Severity: normal

Details

Reference
bz1244
TitleReferenceAuthorSource BranchDest Branch
Add analytics webrequest and pageview actor dagsrepos/data-engineering/airflow-dags!223joalwebrequest_actormain
Customize query in GitLab

Event Timeline

bzimport raised the priority of this task from to Medium.Nov 21 2014, 8:08 PM
bzimport set Reference to bz1244.
bzimport added a subscriber: Unknown Object (MLST).

jeluf wrote:

How to specify FOR UPDATE in a UNION?

SELECT * FROM ipblocks WHERE ipb_address = '127.0.0.1'
UNION SELECT * FROM ipblocks WHERE ipb_user=33 FOR UPDATE;

> ERROR 1234: Wrong usage/placement of 'UPDATE'

christof wrote:

the latest change breaks with mysql 3.23

fvw.wikipediabz wrote:

Backport of patch to HEAD to use union for blocklog selects

attachment mediawiki-1.4b5-blockcheck-optimise.diff ignored as obsolete

fvw.wikipediabz wrote:

MySQL 3.23 doesn't do union. If you get the "ERROR 1234: Wrong usage/placement of 'UPDATE'" error when using FOR UPDATE, you'll
have to upgrade too, it looks like earlier versions of MySQL didn't like the combination of FOR UPDATE and UNION.

fvw.wikipediabz wrote:

Updated patch to not use unions on mysql 3.x

Ok, here's a fresh patch that doesn't use UNION on MySQL 3.x. If you're
performance concious and still on MySQL 3.x you'll want to split it into two
separate selects and concat the results in PHP though (though this patch
doesn't make matters worse for you).

Attached:

jeluf wrote:

+ } elseif ( $options=='' || $wgDBmysql4!=true) {

I think this one should be

+ } elseif ( $options=='' && $wgDBmysql4==true) {

Hardcodes for different databases are quite ugly. We try to move those things
into the Database classes. It would be nice not to have to put this into Block.php

Marked as fixed-in-cvs. Since we're starting the 1.5 beta cycle, resolving as FIXED.