From 3342fafb4839a27b0be3a6e02149e1accf63cc87 Mon Sep 17 00:00:00 2001 From: Brian Wolff Date: Fri, 7 Jun 2013 14:29:56 -0300 Subject: [PATCH] Make Special:MIMESearch a non-expensive special page. This tries to use the index on (img_media_type, img_major_mime, img_minor_mime). This is not the ideal index for this purpose (due to starting with img_media_type, and not having an img_name at the end). However it seems usable due to the low number of values img_media_type can have. Thus we can just specify all values, and the index will get used as a range index. The only potentially problematic thing I see is that it uses LIMIT X,Y for the offsets (due to being a query page) which can be expensive on big offsets. If that's an issue, we could limit the number of results to be at most $wgQueryCacheLimit or something. Note: There's some discussion on the bug rather negative to this special page in general. While I agree with much of the criticism, I still think this special page can be useful, and if it can be made efficient without needing to modify the indicies, we might as well. Bug: 13438 Change-Id: I88826ae7bff0812374157e596f86a19b248220e1 --- RELEASE-NOTES-1.22 | 1 + includes/QueryPage.php | 2 +- includes/specials/SpecialMIMEsearch.php | 39 +++++++++++++++++++++---- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/RELEASE-NOTES-1.22 b/RELEASE-NOTES-1.22 index 68e14dc7b1..c1f91bc83b 100644 --- a/RELEASE-NOTES-1.22 +++ b/RELEASE-NOTES-1.22 @@ -217,6 +217,7 @@ production. for non-inclusion in ApiQueryQueryPages. * (bug 50870) mediawiki.notification: Notification area should remain visible when scrolled down. +* (bug 13438) Special:MIMESearch no longer an expensive special page. === API changes in 1.22 === * (bug 25553) The JSON output formatter now leaves forward slashes unescaped diff --git a/includes/QueryPage.php b/includes/QueryPage.php index 0abeb31e0f..699c843c49 100644 --- a/includes/QueryPage.php +++ b/includes/QueryPage.php @@ -588,7 +588,7 @@ abstract class QueryPage extends SpecialPage { # $res might contain the whole 1,000 rows, so we read up to # $num [should update this to use a Pager] - for ( $i = 0; $i < $num && $row = $dbr->fetchObject( $res ); $i++ ) { + for ( $i = 0; $i < $num && $row = $res->fetchObject(); $i++ ) { $line = $this->formatResult( $skin, $row ); if ( $line ) { $attr = ( isset( $row->usepatrol ) && $row->usepatrol && $row->patrolled == 0 ) diff --git a/includes/specials/SpecialMIMEsearch.php b/includes/specials/SpecialMIMEsearch.php index 7ff5d7b550..3eeae310e0 100644 --- a/includes/specials/SpecialMIMEsearch.php +++ b/includes/specials/SpecialMIMEsearch.php @@ -35,7 +35,7 @@ class MIMEsearchPage extends QueryPage { } function isExpensive() { - return true; + return false; } function isSyndicated() { @@ -51,12 +51,14 @@ class MIMEsearchPage extends QueryPage { } public function getQueryInfo() { - return array( + $qi = array( 'tables' => array( 'image' ), 'fields' => array( 'namespace' => NS_FILE, 'title' => 'img_name', - 'value' => 'img_major_mime', + // Still have a value field just in case, + // but it isn't actually used for sorting. + 'value' => 'img_name', 'img_size', 'img_width', 'img_height', @@ -65,9 +67,36 @@ class MIMEsearchPage extends QueryPage { ), 'conds' => array( 'img_major_mime' => $this->major, - 'img_minor_mime' => $this->minor - ) + 'img_minor_mime' => $this->minor, + // This is in order to trigger using + // the img_media_mime index in "range" mode. + 'img_media_type' => array( + MEDIATYPE_BITMAP, + MEDIATYPE_DRAWING, + MEDIATYPE_AUDIO, + MEDIATYPE_VIDEO, + MEDIATYPE_MULTIMEDIA, + MEDIATYPE_UNKNOWN, + MEDIATYPE_OFFICE, + MEDIATYPE_TEXT, + MEDIATYPE_EXECUTABLE, + MEDIATYPE_ARCHIVE, + ), + ), ); + return $qi; + } + + /** + * The index is on (img_media_type, img_major_mime, img_minor_mime) + * which unfortunately doesn't have img_name at the end for sorting. + * So tell db to sort it however it wishes (Its not super important + * that this report gives results in a logical order). As an aditional + * note, mysql seems to by default order things by img_name ASC, which + * is what we ideally want, so everything works out fine anyhow. + */ + function getOrderFields() { + return array(); } function execute( $par ) { -- 2.20.1