我有一张超过12列的表格。这是用于检索最新7条记录的mysql查询
SELECT * FROM data WHERE user_id IN(12,10,7,1) HAVING continent IN('Europe','America','Australia') AND NOT MATCH(weather) AGAINST('+"[blues]"' IN BOOLEAN MODE) || continent = 'Asia' AND MATCH(weather) AGAINST('+"[purples]"' IN BOOLEAN MODE) ORDER BY tb_id DESC LIMIT 7
总行数超过5 million
,user_id
是一个索引列,tb_id
为PRIMARY KEY
。当我使用EXPLAIN
前面的SELECT
时。 MySQL告诉它将从总计500万条中读取超过40万条记录。
那么我应该对大陆专栏进行索引,否则在这种情况下无效?
这是EXPLAIN结果
id = 1; select_type = SIMPLE; table = data; possible_keys = user_id; key = user_id; ref = NULL; rows = 582; Extra = Using where, Using filesort
答案 0 :(得分:1)
首先,您的查询可能是错误的。当您在{或1}}中使用OR
与where或者where子句中的AND
混合时,您应该使用parantheses。
其次,在您的情况下使用HAVING没有意义,优化器很可能将其转换为WHERE子句。
两者之间的区别在于,在确定要选择的行时应用WHERE
。 HAVING
应用于结果集。所以,如果优化器不能很好地完成,你首先会得到(差不多)所有行,然后对它们进行过滤。当你把它全部放在WHERE
子句中时,你只得到相关的行。 HAVING
(几乎)仅在您使用GROUP BY
时才有意义。
因此,您最好以这种方式编写查询:
SELECT * FROM data
WHERE user_id IN(12,10,7,1) AND
(
(
continent IN('Europe','America','Australia')
AND NOT MATCH(weather) AGAINST('+"[blues]"' IN BOOLEAN MODE)
)
OR
(
continent = 'Asia'
AND MATCH(weather) AGAINST('+"[purples]"' IN BOOLEAN MODE)
)
)
ORDER BY tb_id DESC LIMIT 7
要回答有关索引的问题,请发布解释结果和表data
的创建语句。