简体   繁体   English

优化 MySQL FULL TEXT 搜索

[英]Optimize MySQL FULL TEXT search

I have a search with only one field that allows me to search in several columns of a MySQL table.我的搜索只有一个字段,允许我在 MySQL 表的几列中进行搜索。

This is the SQL query:这是 SQL 查询:

SELECT td__user.*
FROM td__user LEFT JOIN td__user_oauth ON td__user.id = td__user_oauth.user_id 
WHERE ( td__user.id LIKE "contact@mywebsite.com" OR (MATCH (email, firstname, lastname) AGAINST (+"contact@mywebsite.com" IN BOOLEAN MODE)) ) 
ORDER BY date_accountcreated DESC LIMIT 20 OFFSET 0

The exact SQL query with PHP pre-processing of the search field to separate each word:精确的 SQL 查询,使用 PHP 预处理搜索字段以分隔每个单词:

if($_POST['search'] == '') {
    $searchId = '%';
} else {
    $searchId = $_POST['search'];
}

$searchMatch = '';
foreach($arrayWords as $word) {
    $searchMatch .= '+"'.$word.'" ';
}

$sqlSearch = $dataBase->prepare('SELECT td__user.*,
                                        td__user_oauth.facebook_id, td__user_oauth.google_id
                                 FROM td__user
                                 LEFT JOIN td__user_oauth ON td__user.id = td__user_oauth.user_id
                                 WHERE (
                                         td__user.id LIKE :id OR 
                                         (MATCH (email, firstname, lastname) AGAINST (:match IN BOOLEAN MODE)) ) 

                                 ORDER BY date_accountcreated DESC LIMIT 20 OFFSET 0);

$sqlSearch->execute(['id'    => $searchId,
                     'match' => $searchMatch]);

$searchResult = $sqlSearch->fetchAll();
$sqlSearch->closeCursor();

And these are my index:这些是我的索引: 在此处输入图像描述

The SQL query works well, when I put an ID in the search field or a first name or a last name, or an email even not complete I have results. SQL 查询效果很好,当我在搜索字段中输入 ID 或名字或姓氏,或 email 甚至不完整时,我有结果。 I can also put a first name and a last name in my search field and I will only result in people with this name.我也可以在我的搜索字段中输入名字和姓氏,我只会找到具有这个名字的人。

On the other hand, in a table containing 500,000 contacts, the query takes more than 5 seconds.另一方面,在包含 500,000 个联系人的表中,查询时间超过 5 秒。 Are there any possible points for improvement in the query or in the indexes to be done in order to have a faster query?为了更快的查询,查询或索引是否有任何可能的改进点?

Did you try to use "UNION" 2 sets of results instead of using the "OR" operator in the "WHERE" clause?您是否尝试在“WHERE”子句中使用“UNION”2 组结果而不是使用“OR”运算符? Because I'm just afraid of the index can not be used with the "OR" operator.因为我只是怕索引不能与“OR”运算符一起使用。

The query will be something like this:查询将是这样的:

SELECT td__user.*,
    td__user_oauth.facebook_id, 
    td__user_oauth.google_id
FROM td__user
LEFT JOIN td__user_oauth ON td__user.id = td__user_oauth.user_id
WHERE td__user.id LIKE :id

UNION
SELECT td__user.*,
    td__user_oauth.facebook_id, 
    td__user_oauth.google_id
FROM td__user
LEFT JOIN td__user_oauth ON td__user.id = td__user_oauth.user_id
WHERE MATCH (email, firstname, lastname) AGAINST (:match IN BOOLEAN MODE))

ORDER BY date_accountcreated DESC LIMIT 20 OFFSET 0

Hope this can help!希望这可以帮助!

FULLTEXT is fast; FULLTEXT很快; LIKE with a leading % is slow; LIKE%开头很慢; OR is slow. OR很慢。

Consider this approach:考虑这种方法:

  1. Run the MATCH part of the query.运行查询的MATCH部分。
  2. If no results, then run the LIKE query but only allow trailing wildcards.如果没有结果,则运行LIKE查询,但只允许使用尾随通配符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM