From da0587965667df3d18881e314f035e03fa1eb850 Mon Sep 17 00:00:00 2001 From: Andrew Garrett Date: Tue, 31 Mar 2009 13:01:05 +0000 Subject: [PATCH] Fix tag filtering by adding a FORCE INDEX to the relevant queries --- includes/ChangeTags.php | 8 ++++++-- includes/LogEventsList.php | 2 +- includes/PageHistory.php | 7 ++++++- includes/specials/SpecialContributions.php | 8 ++++++-- includes/specials/SpecialNewpages.php | 7 ++++++- includes/specials/SpecialRecentchanges.php | 19 ++++++++++++++----- .../specials/SpecialRecentchangeslinked.php | 11 +++++++++-- includes/specials/SpecialWatchlist.php | 2 +- 8 files changed, 49 insertions(+), 15 deletions(-) diff --git a/includes/ChangeTags.php b/includes/ChangeTags.php index 7432086b9d..de804c5c95 100644 --- a/includes/ChangeTags.php +++ b/includes/ChangeTags.php @@ -90,7 +90,8 @@ class ChangeTags { * Handles selecting tags, and filtering. * Needs $tables to be set up properly, so we can figure out which join conditions to use. */ - static function modifyDisplayQuery( &$tables, &$fields, &$conds, &$join_conds, $filter_tag = false ) { + static function modifyDisplayQuery( &$tables, &$fields, &$conds, + &$join_conds, &$options, $filter_tag = false ) { global $wgRequest, $wgUseTagFilter; if ($filter_tag === false) { @@ -118,6 +119,9 @@ class ChangeTags { // Somebody wants to filter on a tag. // Add an INNER JOIN on change_tag + // FORCE INDEX -- change_tags will almost ALWAYS be the correct query plan. + $options['USE INDEX'] = array( 'change_tag' => 'change_tag_tag_id' ); + unset( $options['FORCE INDEX'] ); $tables[] = 'change_tag'; $join_conds['change_tag'] = array( 'INNER JOIN', "ct_$join_cond=$join_cond" ); $conds['ct_tag'] = $filter_tag; @@ -176,4 +180,4 @@ class ChangeTags { $wgMemc->set( $key, $emptyTags, 300 ); return $emptyTags; } -} \ No newline at end of file +} diff --git a/includes/LogEventsList.php b/includes/LogEventsList.php index 9d2de44ada..f0b2756e19 100644 --- a/includes/LogEventsList.php +++ b/includes/LogEventsList.php @@ -651,7 +651,7 @@ class LogPager extends ReverseChronologicalPager { ); ChangeTags::modifyDisplayQuery( $info['tables'], $info['fields'], $info['conds'], - $info['join_conds'], $this->mTagFilter ); + $info['join_conds'], $info['options'], $this->mTagFilter ); return $info; } diff --git a/includes/PageHistory.php b/includes/PageHistory.php index 900718772b..a137235a91 100644 --- a/includes/PageHistory.php +++ b/includes/PageHistory.php @@ -579,7 +579,12 @@ class PageHistoryPager extends ReverseChronologicalPager { 'options' => array( 'USE INDEX' => array('revision' => 'page_timestamp') ), 'join_conds' => array( 'tag_summary' => array( 'LEFT JOIN', 'ts_rev_id=rev_id' ) ), ); - ChangeTags::modifyDisplayQuery( $queryInfo['tables'], $queryInfo['fields'], $queryInfo['conds'], $queryInfo['join_conds'], $this->tagFilter ); + ChangeTags::modifyDisplayQuery( $queryInfo['tables'], + $queryInfo['fields'], + $queryInfo['conds'], + $queryInfo['join_conds'], + $queryInfo['options'], + $this->tagFilter ); wfRunHooks( 'PageHistoryPager::getQueryInfo', array( &$this, &$queryInfo ) ); return $queryInfo; } diff --git a/includes/specials/SpecialContributions.php b/includes/specials/SpecialContributions.php index 6d4dce6806..7be49500ad 100644 --- a/includes/specials/SpecialContributions.php +++ b/includes/specials/SpecialContributions.php @@ -412,8 +412,12 @@ class ContribsPager extends ReverseChronologicalPager { 'join_conds' => $join_cond ); - ChangeTags::modifyDisplayQuery( $queryInfo['tables'], $queryInfo['fields'], $queryInfo['conds'], - $queryInfo['join_conds'], $this->tagFilter ); + ChangeTags::modifyDisplayQuery( $queryInfo['tables'], + $queryInfo['fields'], + $queryInfo['conds'], + $queryInfo['join_conds'], + $queryInfo['options'], + $this->tagFilter ); wfRunHooks( 'ContribsPager::getQueryInfo', array( &$this, &$queryInfo ) ); return $queryInfo; diff --git a/includes/specials/SpecialNewpages.php b/includes/specials/SpecialNewpages.php index 9cf71777a3..886c41a254 100644 --- a/includes/specials/SpecialNewpages.php +++ b/includes/specials/SpecialNewpages.php @@ -438,7 +438,12 @@ class NewPagesPager extends ReverseChronologicalPager { $fields = array(); ## Modify query for tags - ChangeTags::modifyDisplayQuery( $info['tables'], $fields, $info['conds'], $info['join_conds'], $this->opts['tagfilter'] ); + ChangeTags::modifyDisplayQuery( $info['tables'], + $fields, + $info['conds'], + $info['join_conds'], + $info['options'], + $this->opts['tagfilter'] ); return $info; } diff --git a/includes/specials/SpecialRecentchanges.php b/includes/specials/SpecialRecentchanges.php index b0eb591dd4..91c0ecbedb 100644 --- a/includes/specials/SpecialRecentchanges.php +++ b/includes/specials/SpecialRecentchanges.php @@ -270,6 +270,7 @@ class SpecialRecentChanges extends SpecialPage { $tables = array( 'recentchanges' ); $join_conds = array(); + $query_options = array( 'USE INDEX' => array('recentchanges' => 'rc_timestamp') ); $uid = $wgUser->getId(); $dbr = wfGetDB( DB_SLAVE ); @@ -290,17 +291,25 @@ class SpecialRecentChanges extends SpecialPage { $join_conds['page'] = array('LEFT JOIN', 'rc_cur_id=page_id'); } // Tag stuff. - $fields = array(); // Fields are * in this case, so let the function modify an empty array to keep it happy. - ChangeTags::modifyDisplayQuery( $tables, $fields, $conds, $join_conds, $opts['tagfilter'] ); + $fields = array(); + // Fields are * in this case, so let the function modify an empty array to keep it happy. + ChangeTags::modifyDisplayQuery( $tables, + $fields, + $conds, + $join_conds, + $query_options, + $opts['tagfilter'] + ); wfRunHooks('SpecialRecentChangesQuery', array( &$conds, &$tables, &$join_conds, $opts ) ); // Is there either one namespace selected or excluded? + // Tag filtering also has a better index. // Also, if this is "all" or main namespace, just use timestamp index. - if( is_null($namespace) || $invert || $namespace == NS_MAIN ) { + if( is_null($namespace) || $invert || $namespace == NS_MAIN || $opts['tagfilter'] ) { $res = $dbr->select( $tables, '*', $conds, __METHOD__, - array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit, - 'USE INDEX' => array('recentchanges' => 'rc_timestamp') ), + array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit ) + + $query_options, $join_conds ); // We have a new_namespace_time index! UNION over new=(0,1) and sort result set! } else { diff --git a/includes/specials/SpecialRecentchangeslinked.php b/includes/specials/SpecialRecentchangeslinked.php index 1812eb6836..2a490c9199 100644 --- a/includes/specials/SpecialRecentchangeslinked.php +++ b/includes/specials/SpecialRecentchangeslinked.php @@ -76,6 +76,7 @@ class SpecialRecentchangeslinked extends SpecialRecentchanges { $tables = array( 'recentchanges' ); $select = array( $dbr->tableName( 'recentchanges' ) . '.*' ); $join_conds = array(); + $query_options = array(); // left join with watchlist table to highlight watched rows if( $uid = $wgUser->getId() ) { @@ -84,7 +85,13 @@ class SpecialRecentchangeslinked extends SpecialRecentchanges { $join_conds['watchlist'] = array( 'LEFT JOIN', "wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace" ); } - ChangeTags::modifyDisplayQuery( $tables, $select, $conds, $join_conds, $opts['tagfilter'] ); + ChangeTags::modifyDisplayQuery( $tables, + $select, + $conds, + $join_conds, + $query_options, + $opts['tagfilter'], + ); // XXX: parent class does this, should we too? // wfRunHooks('SpecialRecentChangesQuery', array( &$conds, &$tables, &$join_conds, $opts ) ); @@ -142,7 +149,7 @@ class SpecialRecentchangeslinked extends SpecialRecentchanges { $select, $conds + $subconds, __METHOD__, - array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit ), + array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit ) + $query_options, $join_conds + array( $link_table => array( 'INNER JOIN', $subjoin ) ) ); } diff --git a/includes/specials/SpecialWatchlist.php b/includes/specials/SpecialWatchlist.php index 79f054d0e9..b14577b552 100644 --- a/includes/specials/SpecialWatchlist.php +++ b/includes/specials/SpecialWatchlist.php @@ -222,7 +222,7 @@ function wfSpecialWatchlist( $par ) { $fields[] = 'page_latest'; } - ChangeTags::modifyDisplayQuery( $tables, $fields, $conds, $join_conds, '' ); + ChangeTags::modifyDisplayQuery( $tables, $fields, $conds, $join_conds, $options, '' ); wfRunHooks('SpecialWatchlistQuery', array(&$conds,&$tables,&$join_conds,&$fields) ); $res = $dbr->select( $tables, $fields, $conds, __METHOD__, $options, $join_conds ); -- 2.20.1