Оптимизируйте поиск MySQL FULL TEXT - PullRequest
1 голос
/ 18 октября 2019

У меня есть поиск только с одним полем, которое позволяет мне искать в нескольких столбцах таблицы MySQL.

Это запрос 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

Точный запрос 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();

И вот мой индекс: enter image description here

SQL-запрос работает хорошо, когдаЯ ввел идентификатор в поле поиска, или имя, или фамилию, или электронное письмо, даже не заполненное. У меня есть результаты. Я также могу указать имя и фамилию в поле поиска, и я приведу только людей с таким именем.

С другой стороны, в таблице, содержащей 500 000 контактов, запрос занимает более 5секунд. Есть ли какие-либо возможные точки для улучшения в запросе или в индексах, которые должны быть выполнены, чтобы иметь более быстрый запрос?

1 Ответ

1 голос
/ 18 октября 2019

Вы пытались использовать 2 набора результатов UNION вместо оператора «OR» в предложении «WHERE»? Потому что я просто боюсь, что индекс нельзя использовать с оператором «ИЛИ».

Запрос будет выглядеть примерно так:

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

Надеюсь, это поможет!

...