Make Special:MIMESearch a non-expensive special page.
authorBrian Wolff <bawolff+wn@gmail.com>
Fri, 7 Jun 2013 17:29:56 +0000 (14:29 -0300)
committerBrian Wolff <bawolff+wn@gmail.com>
Thu, 25 Jul 2013 03:05:09 +0000 (00:05 -0300)
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
includes/QueryPage.php
includes/specials/SpecialMIMEsearch.php

index 68e14dc..c1f91bc 100644 (file)
@@ -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
index 0abeb31..699c843 100644 (file)
@@ -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 )
index 7ff5d7b..3eeae31 100644 (file)
@@ -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 ) {