Skip to content

Commit

Permalink
Improve search query performance (see #1678)
Browse files Browse the repository at this point in the history
Description
-----------

This pull request improves the search query performance.

1. 792499a moves the word matching into a subselect which seems to help MySQL make better use of the indexes.
2. a2ce8e8 removes the extra counting of wildcards if it is a wildcard-only search because the count is not needed in this case.

In my tests with a `tl_search_index` table with about 1.5 million rows it took down a search like `*foo*` from 10 seconds to 1 second, and `*foo* *bar*` from 12 to 1.3 seconds.

Commits
-------

792499af Improve search query performance
a2ce8e84 Only count wildcard matches if necessary
ec39a0cd Merge branch '4.4' into fix/search-query-performance
  • Loading branch information
ausi committed Apr 30, 2020
1 parent ce400d2 commit 0c0a2ab
Showing 1 changed file with 12 additions and 5 deletions.
17 changes: 12 additions & 5 deletions src/Resources/contao/library/Contao/Search.php
Original file line number Diff line number Diff line change
Expand Up @@ -403,10 +403,10 @@ public static function searchFor($strKeywords, $blnOrSearch=false, $arrPid=array
$arrValues = array();

// Remember found words so we can highlight them later
$strQuery = "SELECT * FROM (SELECT tl_search_index.pid AS sid, GROUP_CONCAT(word) AS matches";
$strQuery = "SELECT * FROM (SELECT tl_search_index.pid AS sid, GROUP_CONCAT(tl_search_index.word) AS matches";

// Get the number of wildcard matches
if (!$blnOrSearch && $intWildcards)
// Get the number of wildcard matches if wildcards and keywords are mixed
if (!$blnOrSearch && $intWildcards && (\count($arrKeywords) || $intIncluded || $intPhrases))
{
$strQuery .= ", (SELECT COUNT(*) FROM tl_search_index WHERE (" . implode(' OR ', array_fill(0, $intWildcards, 'word LIKE ?')) . ") AND pid=sid) AS wildcards";
$arrValues = array_merge($arrValues, $arrWildcards);
Expand Down Expand Up @@ -456,7 +456,7 @@ public static function searchFor($strKeywords, $blnOrSearch=false, $arrPid=array
$arrValues = array_merge($arrValues, $arrWildcards);
}

$strQuery .= " FROM tl_search_index WHERE (" . implode(' OR ', $arrAllKeywords) . ")";
$strQuery .= " FROM (SELECT word FROM tl_search_index WHERE (" . implode(' OR ', $arrAllKeywords) . ") GROUP BY word) words JOIN tl_search_index ON tl_search_index.word = words.word WHERE 1";

// Get phrases
if ($intPhrases)
Expand Down Expand Up @@ -499,7 +499,14 @@ public static function searchFor($strKeywords, $blnOrSearch=false, $arrPid=array
// Dynamically add the number of wildcard matches
if ($intWildcards)
{
$strQuery .= " + IF(matches.wildcards>" . $intWildcards . ", matches.wildcards, " . $intWildcards . ")";
if ($intKeywords)
{
$strQuery .= " + IF(matches.wildcards>" . $intWildcards . ", matches.wildcards, " . $intWildcards . ")";
}
else
{
$strQuery .= " + " . $intWildcards;
}
}
}

Expand Down

0 comments on commit 0c0a2ab

Please sign in to comment.