В зависимости от того, чего вы хотите достичь, вам следует либо заменить LEFT JOIN
на INNER JOIN
, либо переместить условие WHERE
в предложение ON
:
Как сейчас:
SELECT a.*
FROM `tff__keywords2data` AS a
LEFT JOIN
`tff__keywords` AS b
ON b.id = a.keyword_id
WHERE b.keyword = 'dog' || b.keyword = 'black' || b.keyword = 'and' || b.keyword = 'white'
GROUP BY
a.data_id
HAVING COUNT( a.data_id ) = 4
Ваш запрос фактически является соединением INNER
(поскольку в предложении WHERE
имеются ненулевые условия).
Кроме того, вместо использования битовой арифметики (которая не может быть sargable) вы должны использовать собственные конструкции OR
или IN
:
SELECT a.*
FROM `tff__keywords2data` AS a
JOIN `tff__keywords` AS b
ON b.id = a.keyword_id
WHERE b.keyword IN ('dog', 'black', 'and', 'white')
GROUP BY
a.data_id
HAVING COUNT(*) = 4
Вы также можете создать индекс на ttf__keywords (keyword)
, который может фильтровать на keywords
, который вы ищете, и делать меньше записей для выбора из ведущих b
.
Наконец, если вам не нужно неявное упорядочение a.data_id
, избавьтесь от него, добавив ORDER BY NULL
:
SELECT a.*
FROM `tff__keywords2data` AS a
JOIN `tff__keywords` AS b
ON b.id = a.keyword_id
WHERE b.keyword IN ('dog', 'black', 'and', 'white')
GROUP BY
a.data_id
HAVING COUNT(*) = 4
ORDER BY
NULL
Это удалит filesort
из вашего плана.