X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fapi%2FApiQueryBacklinksprop.php;h=8e89c32e50d0c2798819ed0a2342906f9d54c57e;hb=724b2cf91205cc1b09c5677a8c01e34978717d4a;hp=17b51da432084ec534ca7945ff88e1cd2f95a9b0;hpb=f9d7d3b8561dab3ddfd8798a77a5b72e03ac8c2b;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/api/ApiQueryBacklinksprop.php b/includes/api/ApiQueryBacklinksprop.php index 17b51da432..8e89c32e50 100644 --- a/includes/api/ApiQueryBacklinksprop.php +++ b/includes/api/ApiQueryBacklinksprop.php @@ -53,6 +53,7 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase { 'code' => 'lh', 'prefix' => 'pl', 'linktable' => 'pagelinks', + 'indexes' => [ 'pl_namespace', 'pl_backlinks_namespace' ], 'from_namespace' => true, 'showredirects' => true, ], @@ -60,6 +61,7 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase { 'code' => 'ti', 'prefix' => 'tl', 'linktable' => 'templatelinks', + 'indexes' => [ 'tl_namespace', 'tl_backlinks_namespace' ], 'from_namespace' => true, 'showredirects' => true, ], @@ -67,6 +69,7 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase { 'code' => 'fu', 'prefix' => 'il', 'linktable' => 'imagelinks', + 'indexes' => [ 'il_to', 'il_backlinks_namespace' ], 'from_namespace' => true, 'to_namespace' => NS_FILE, 'exampletitle' => 'File:Example.jpg', @@ -164,22 +167,14 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase { $this->dieContinueUsageIf( count( $cont ) != count( $sortby ) ); $where = ''; $i = count( $sortby ) - 1; - $cont_ns = 0; - $cont_title = ''; foreach ( array_reverse( $sortby, true ) as $field => $type ) { $v = $cont[$i]; switch ( $type ) { case 'ns': - $cont_ns = (int)$v; - /* fall through */ case 'int': $v = (int)$v; $this->dieContinueUsageIf( $v != $cont[$i] ); break; - - case 'title': - $cont_title = $v; - /* fall through */ default: $v = $db->addQuotes( $v ); break; @@ -257,6 +252,24 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase { // Override any ORDER BY from above with what we calculated earlier. $this->addOption( 'ORDER BY', array_keys( $sortby ) ); + // MySQL's optimizer chokes if we have too many values in "$bl_title IN + // (...)" and chooses the wrong index, so specify the correct index to + // use for the query. See T139056 for details. + if ( !empty( $settings['indexes'] ) ) { + list( $idxNoFromNS, $idxWithFromNS ) = $settings['indexes']; + if ( $params['namespace'] !== null && !empty( $settings['from_namespace'] ) ) { + $this->addOption( 'USE INDEX', [ $settings['linktable'] => $idxWithFromNS ] ); + } else { + $this->addOption( 'USE INDEX', [ $settings['linktable'] => $idxNoFromNS ] ); + } + } + + // MySQL (or at least 5.5.5-10.0.23-MariaDB) chooses a really bad query + // plan if it thinks there will be more matching rows in the linktable + // than are in page. Use STRAIGHT_JOIN here to force it to use the + // intended, fast plan. See T145079 for details. + $this->addOption( 'STRAIGHT_JOIN' ); + $this->addOption( 'LIMIT', $params['limit'] + 1 ); $res = $this->select( __METHOD__ ); @@ -321,7 +334,7 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase { foreach ( $sortby as $field => $v ) { $cont[] = $row->$field; } - $this->setContinueEnumParameter( 'continue', join( '|', $cont ) ); + $this->setContinueEnumParameter( 'continue', implode( '|', $cont ) ); } public function getCacheMode( $params ) {