Brian Wolff has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/67468


Change subject: Make Special:MIMESearch a non-expensive special page.
......................................................................

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 workable. It does a couple extra queries (at worst 9, one
for each media type defined. However the common case of a bitmap
image, it doesn't need any extra queries. These extra queries should
be cheap indexed 0 result queries). Additionally, even though the
index doesn't have img_name on the end, mysql seems to return
results in img_name ASC order, which is nice (Even if it didn't,
I still think this change would be worth it).

I've does DESCRIBE on all the queries, and they look good to me.
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
---
M RELEASE-NOTES-1.22
M includes/QueryPage.php
M includes/specials/SpecialMIMEsearch.php
3 files changed, 62 insertions(+), 5 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/68/67468/1

diff --git a/RELEASE-NOTES-1.22 b/RELEASE-NOTES-1.22
index 07763d9..327684c 100644
--- a/RELEASE-NOTES-1.22
+++ b/RELEASE-NOTES-1.22
@@ -132,6 +132,7 @@
 * (bug 48294) API: Fix chunk upload async mode.
 * (bug 46749) Broken files tracking category removed from pages if an image
   with that name is uploaded.
+* (bug 13438) Special:MIMESearch no longer an expensive special page.
 
 === API changes in 1.22 ===
 * (bug 46626) xmldoublequote parameter was removed. Because of a bug, the
diff --git a/includes/QueryPage.php b/includes/QueryPage.php
index a93639a..e96c7bd 100644
--- a/includes/QueryPage.php
+++ b/includes/QueryPage.php
@@ -588,7 +588,7 @@
 
                        # $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 7ff5d7b..4a4a4e1 100644
--- a/includes/specials/SpecialMIMEsearch.php
+++ b/includes/specials/SpecialMIMEsearch.php
@@ -28,14 +28,14 @@
  * @ingroup SpecialPage
  */
 class MIMEsearchPage extends QueryPage {
-       protected $major, $minor;
+       protected $major, $minor, $mediaType = false;
 
        function __construct( $name = 'MIMEsearch' ) {
                parent::__construct( $name );
        }
 
        function isExpensive() {
-               return true;
+               return false;
        }
 
        function isSyndicated() {
@@ -51,12 +51,14 @@
        }
 
        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',
@@ -68,6 +70,60 @@
                                'img_minor_mime' => $this->minor
                        )
                );
+               if ( $this->mediaType ) {
+                       $qi['conds']['img_media_type'] = $this->mediaType;
+               }
+               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();
+       }
+
+       /**
+        * Work around the index structure of the db, where we
+        * have to first search for img_media_type. Luckily there
+        * is only a limitted number of such types, so we can
+        * just do a bunch of indexed queries (most of which would
+        * be quick 0 results).
+        */
+       function reallyDoQuery( $limit, $offset = false ) {
+               $mediaTypes = array(
+                       MEDIATYPE_BITMAP,
+                       MEDIATYPE_DRAWING,
+                       MEDIATYPE_AUDIO,
+                       MEDIATYPE_VIDEO,
+                       MEDIATYPE_MULTIMEDIA,
+                       MEDIATYPE_UNKNOWN,
+                       MEDIATYPE_OFFICE,
+                       MEDIATYPE_TEXT,
+                       MEDIATYPE_EXECUTABLE,
+                       MEDIATYPE_ARCHIVE,
+               );
+               $results = array();
+               $curLimit = $limit; // Number of results left to fetch
+
+               foreach( $mediaTypes as $curMediaType ) {
+                       $this->mediaType = $curMediaType;
+                       $tmpResult = parent::reallyDoQuery( $curLimit, $offset 
);
+                       foreach( $tmpResult as $row ) {
+                               $results[] = $row;
+                               $curLimit--;
+                       }
+                       if ( $curLimit <= 0 ) {
+                               break;
+                       }
+               }
+               $this->mediaType = false;
+               return new FakeResultWrapper( $results );
        }
 
        function execute( $par ) {

-- 
To view, visit https://gerrit.wikimedia.org/r/67468
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I88826ae7bff0812374157e596f86a19b248220e1
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Brian Wolff <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to