From f212ddabae151b38c65d514bed08873e30cd22bf Mon Sep 17 00:00:00 2001 From: Roan Kattouw Date: Mon, 28 Mar 2011 15:01:20 +0000 Subject: [PATCH] BREAKING CHANGE: Ignore cmtype when cmsort=timestamp is set, and bypass the per-type queries in the sort=timestamp case; they were causing performance problems, reported as bug 28291. This breaks backwards compatibility (gracefully, the cltype parameter is silently ignored) with earlier deployed versions of 1.17wmf1 but not with any released version, hence no RELEASE-NOTES --- includes/api/ApiQueryCategoryMembers.php | 48 ++++++++++++++---------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/includes/api/ApiQueryCategoryMembers.php b/includes/api/ApiQueryCategoryMembers.php index 5f249b2a16..d48458d6b8 100644 --- a/includes/api/ApiQueryCategoryMembers.php +++ b/includes/api/ApiQueryCategoryMembers.php @@ -160,26 +160,34 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase { $limit = $params['limit']; $this->addOption( 'LIMIT', $limit + 1 ); - // Run a separate SELECT query for each value of cl_type. - // This is needed because cl_type is an enum, and MySQL has - // inconsistencies between ORDER BY cl_type and - // WHERE cl_type >= 'foo' making proper paging impossible - // and unindexed. - $rows = array(); - $first = true; - foreach ( $queryTypes as $type ) { - $extraConds = array( 'cl_type' => $type ); - if ( $first && $contWhere ) { - // Continuation condition. Only added to the - // first query, otherwise we'll skip things - $extraConds[] = $contWhere; - } - $res = $this->select( __METHOD__, array( 'where' => $extraConds ) ); - $rows = array_merge( $rows, iterator_to_array( $res ) ); - if ( count( $rows ) >= $limit + 1 ) { - break; + if ( $params['sort'] == 'sortkey' ) { + // Run a separate SELECT query for each value of cl_type. + // This is needed because cl_type is an enum, and MySQL has + // inconsistencies between ORDER BY cl_type and + // WHERE cl_type >= 'foo' making proper paging impossible + // and unindexed. + $rows = array(); + $first = true; + foreach ( $queryTypes as $type ) { + $extraConds = array( 'cl_type' => $type ); + if ( $first && $contWhere ) { + // Continuation condition. Only added to the + // first query, otherwise we'll skip things + $extraConds[] = $contWhere; + } + $res = $this->select( __METHOD__, array( 'where' => $extraConds ) ); + $rows = array_merge( $rows, iterator_to_array( $res ) ); + if ( count( $rows ) >= $limit + 1 ) { + break; + } + $first = false; } - $first = false; + } else { + // Sorting by timestamp + // No need to worry about per-type queries because we + // aren't sorting or filtering by type anyway + $res = $this->select( __METHOD__ ); + $rows = iterator_to_array( $res ); } $count = 0; foreach ( $rows as $row ) { @@ -334,7 +342,7 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase { ' timestamp - Adds the timestamp of when the page was included', ), 'namespace' => 'Only include pages in these namespaces', - 'type' => 'What type of category members to include', + 'type' => "What type of category members to include. Ignored when {$p}sort=timestamp is set", 'sort' => 'Property to sort by', 'dir' => 'In which direction to sort', 'start' => "Timestamp to start listing from. Can only be used with {$p}sort=timestamp", -- 2.20.1