Commit ad6d4462 authored by catch's avatar catch
Browse files

Issue #2950869 by amateescu, alexpott, fabianx, lucassc, abhishek-anand,...

Issue #2950869 by amateescu, alexpott, fabianx, lucassc, abhishek-anand, pavlosdan, ravi.shankar, adam.weingarten, timmy_cos, rassoni, bryanmanalo, pooja saraah, _pratik_, enrocean167, matsbla, catch, berdir, wim leers, yakoub, neclimdul, dixon_, camoa, daffie, effulgentsia, mariancalinro, mheip, nicobot, krzysztof domański: Entity queries querying the latest revision very slow with lots of revisions

(cherry picked from commit 88413b86)
parent 1ff17fe3
Loading
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -131,11 +131,16 @@ protected function prepare() {
      $this->sqlFields["base_table.$id_field"] = ['base_table', $id_field];
    }

    // Add a self-join to the base revision table if we're querying only the
    // latest revisions.
    // Use max and group by to only return the latest revision in the most
    // optimal way.
    if ($this->latestRevision && $revision_field) {
      $this->sqlQuery->leftJoin($base_table, 'base_table_2', "[base_table].[$id_field] = [base_table_2].[$id_field] AND [base_table].[$revision_field] < [base_table_2].[$revision_field]");
      $this->sqlQuery->isNull("base_table_2.$id_field");
      // Fetch all latest revision ids in a sub-query.
      $revision_subquery = $this->connection->select($base_table, 'base_table');
      $revision_subquery->addExpression("MAX(base_table.$revision_field)");
      $revision_subquery->groupBy("base_table.$id_field");

      // Restrict results only to latest ids.
      $this->sqlQuery->condition("base_table.$revision_field", $revision_subquery, 'IN');
    }

    if (is_null($this->accessCheck)) {
+26 −1
Original line number Diff line number Diff line
@@ -381,6 +381,31 @@ public function testEntityQuery(): void {
    $assert = [4 => '4', 5 => '5', 6 => '6', 7 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 12 => '12', 20 => '12', 13 => '13', 21 => '13', 14 => '14', 22 => '14', 15 => '15', 23 => '15'];
    $this->assertSame($assert, $results);

    $results = $this->queryResults = $this->storage
      ->getQuery()
      ->latestRevision()
      ->notExists("$figures.color")
      ->accessCheck(TRUE)
      ->execute();
    $expected = [16 => '4', 8 => '8', 20 => '12'];
    $this->assertSame($expected, $results);

    // Update an entity.
    $entity = EntityTestMulRev::load(4);
    $entity->setNewRevision();
    $entity->name->value .= 'x';
    $entity->save();

    // Updated entity should now have revision ID 24.
    $results = $this->queryResults = $this->storage
      ->getQuery()
      ->latestRevision()
      ->notExists("$figures.color")
      ->accessCheck(TRUE)
      ->execute();
    $expected = [24 => '4', 8 => '8', 20 => '12'];
    $this->assertSame($expected, $results);

    // Check that a query on the latest revisions without any condition returns
    // the correct results.
    $results = $this->storage
@@ -390,7 +415,7 @@ public function testEntityQuery(): void {
      ->sort('id')
      ->sort('revision_id')
      ->execute();
    $expected = [1 => '1', 2 => '2', 3 => '3', 16 => '4', 17 => '5', 18 => '6', 19 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 20 => '12', 21 => '13', 22 => '14', 23 => '15'];
    $expected = [1 => '1', 2 => '2', 3 => '3', 24 => '4', 17 => '5', 18 => '6', 19 => '7', 8 => '8', 9 => '9', 10 => '10', 11 => '11', 20 => '12', 21 => '13', 22 => '14', 23 => '15'];
    $this->assertSame($expected, $results);
  }