r74298 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r74297‎ | r74298 | r74299 >
Date:13:36, 5 October 2010
Author:greg
Status:resolved (Comments)
Tags:
Comment:
Make the watchlist query ordering consistent across DBs.
Modified paths:
  • /trunk/phase3/includes/WatchlistEditor.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/WatchlistEditor.php
@@ -212,6 +212,9 @@
213213 $sql = "SELECT wl_namespace, wl_title, page_id, page_len, page_is_redirect, page_latest
214214 FROM {$watchlist} LEFT JOIN {$page} ON ( wl_namespace = page_namespace
215215 AND wl_title = page_title ) WHERE wl_user = {$uid}";
 216+ if ( ! $dbr->implicitOrderby() ) {
 217+ $sql .= " ORDER BY wl_title";
 218+ }
216219 $res = $dbr->query( $sql, __METHOD__ );
217220 if( $res && $dbr->numRows( $res ) > 0 ) {
218221 $cache = LinkCache::singleton();

Follow-up revisions

RevisionCommit summaryAuthorDate
r79864Followup r74298: add ORDER BY wl_namespace, wl_title to the query in Watchlis...catrope16:01, 8 January 2011

Comments

#Comment by Brion VIBBER (talk | contribs)   14:54, 5 October 2010

I think you want 'ORDER BY wl_namespace,wl_title' here (or perhaps 'ORDER BY wl_user,wl_namespace,wl_title' if optimizers get confused).

Is there actually a need for the conditional?

#Comment by Turnstep (talk | contribs)   15:25, 5 October 2010

I seem to recall MySQL folk complaining when I tried out a direct ORDER BY. This was some years ago now, so I may be wrong. Certainly a direct ORDER BY gets my vote.

#Comment by Brion VIBBER (talk | contribs)   15:28, 5 October 2010

On my local MySQL test, EXPLAIN tosses in a 'using where' when using the order by (?) but otherwise doesn't seem to change. I'd defer to scary Domas if he can point out dangers though. :D

Main thing is to make sure that the ordering is correct and doesn't introduce a filesort; ordering just on wl_title will give a different ordering than expected, which doesn't match up to available indexes.

#Comment by Reedy (talk | contribs)   03:00, 6 January 2011
mysql> DESCRIBE SELECT wl_namespace, wl_title, page_id, page_len, page_is_redirect, page_latest FROM mw_watchlist LEFT JOIN mw_page ON ( wl_namespace = page_namespace AND wl_title = page_title ) WHERE wl_user = 1;
+----+-------------+--------------+--------+---------------+------------+---------+---------------------------------------------------------------+------+-------------+
| id | select_type | table        | type   | possible_keys | key        | key_len | ref                                                           | rows | Extra       |
+----+-------------+--------------+--------+---------------+------------+---------+---------------------------------------------------------------+------+-------------+
|  1 | SIMPLE      | mw_watchlist | ref    | wl_user       | wl_user    | 4       | const                                                         |    6 | Using index |
|  1 | SIMPLE      | mw_page      | eq_ref | name_title    | name_title | 261     | wikidb.mw_watchlist.wl_namespace,wikidb.mw_watchlist.wl_title |    1 |             |
+----+-------------+--------------+--------+---------------+------------+---------+---------------------------------------------------------------+------+-------------+
2 rows in set (0.00 sec)

mysql> DESCRIBE SELECT wl_namespace, wl_title, page_id, page_len, page_is_redirect, page_latest FROM mw_watchlist LEFT JOIN mw_page ON ( wl_namespace = page_namespace AND wl_title = page_title ) WHERE wl_user = 1 ORDER BY wl_title;
+----+-------------+--------------+--------+---------------+------------+---------+---------------------------------------------------------------+------+------------------------------------------+
| id | select_type | table        | type   | possible_keys | key        | key_len | ref                                                           | rows | Extra                                    |
+----+-------------+--------------+--------+---------------+------------+---------+---------------------------------------------------------------+------+------------------------------------------+
|  1 | SIMPLE      | mw_watchlist | ref    | wl_user       | wl_user    | 4       | const                                                         |    6 | Using where; Using index; Using filesort |
|  1 | SIMPLE      | mw_page      | eq_ref | name_title    | name_title | 261     | wikidb.mw_watchlist.wl_namespace,wikidb.mw_watchlist.wl_title |    1 |                                          |
+----+-------------+--------------+--------+---------------+------------+---------+---------------------------------------------------------------+------+------------------------------------------+
2 rows in set (0.00 sec)


mysql> DESCRIBE SELECT wl_namespace, wl_title, page_id, page_len, page_is_redirect, page_latest FROM mw_watchlist LEFT JOIN mw_page ON ( wl_namespace = page_namespace AND wl_title = page_title ) WHERE wl_user = 1 ORDER BY wl_namespace, wl_title;
+----+-------------+--------------+--------+---------------+------------+---------+---------------------------------------------------------------+------+--------------------------+
| id | select_type | table        | type   | possible_keys | key        | key_len | ref                                                           | rows | Extra                    |
+----+-------------+--------------+--------+---------------+------------+---------+---------------------------------------------------------------+------+--------------------------+
|  1 | SIMPLE      | mw_watchlist | ref    | wl_user       | wl_user    | 4       | const                                                         |    6 | Using where; Using index |
|  1 | SIMPLE      | mw_page      | eq_ref | name_title    | name_title | 261     | wikidb.mw_watchlist.wl_namespace,wikidb.mw_watchlist.wl_title |    1 |                          |
+----+-------------+--------------+--------+---------------+------------+---------+---------------------------------------------------------------+------+--------------------------+
2 rows in set (0.00 sec)


mysql> DESCRIBE SELECT wl_namespace, wl_title, page_id, page_len, page_is_redirect, page_latest FROM mw_watchlist LEFT JOIN mw_page ON ( wl_namespace = page_namespace AND wl_title = page_title ) WHERE wl_user = 1 ORDER BY wl_user, wl_namespace, wl_title;
+----+-------------+--------------+--------+---------------+------------+---------+---------------------------------------------------------------+------+--------------------------+
| id | select_type | table        | type   | possible_keys | key        | key_len | ref                                                           | rows | Extra                    |
+----+-------------+--------------+--------+---------------+------------+---------+---------------------------------------------------------------+------+--------------------------+
|  1 | SIMPLE      | mw_watchlist | ref    | wl_user       | wl_user    | 4       | const                                                         |    6 | Using where; Using index |
|  1 | SIMPLE      | mw_page      | eq_ref | name_title    | name_title | 261     | wikidb.mw_watchlist.wl_namespace,wikidb.mw_watchlist.wl_title |    1 |                          |
+----+-------------+--------------+--------+---------------+------------+---------+---------------------------------------------------------------+------+--------------------------+
2 rows in set (0.00 sec)

Using no order by is better than order by just wl_title (it starts filesorting) on my dev wiki install..

Trivially easy to fix. Anyone any preferences?

#Comment by Catrope (talk | contribs)   12:52, 6 January 2011

ORDER BY wl_title is bad in MySQL because there is no index on wl_title, just on (wl_user, wl_namespace, wl_title). However, $dbr->implicitOrderBy() returns true on MySQL (and on SQLite), so the bad ORDER BY isn't actually added on MySQL installs, just on Postgres and a few unsupported backends (MSSQL, Oracle, DB2).

If Postgres will work with ORDER BY wl_namespace, wl_title (which is what you should actually use to get the same results as MySQL's implicit ordering), just add that unconditionally.

#Comment by Reedy (talk | contribs)   00:44, 8 January 2011

Can someone with Postgres check on this?

#Comment by Turnstep (talk | contribs)   01:33, 8 January 2011

Postgres is fine with that order by

#Comment by Reedy (talk | contribs)   01:34, 8 January 2011

The one set by this revision? Does it not filesort or anything similar?

#Comment by Turnstep (talk | contribs)   01:42, 8 January 2011

Postgres is fine with 'ORDER BY wl_namespace,wl_title'

#Comment by Catrope (talk | contribs)   16:02, 8 January 2011

Thanks. Added that in r79864

Status & tagging log