【问题标题】:Indexing a column in HAVING clause - MySQL索引 HAVING 子句中的列 - MySQL
【发布时间】:2013-02-06 10:02:00
【问题描述】:

我有一张超过 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 millionuser_id 是一个索引列,tb_idPRIMARY KEY。当我在SELECT 前面使用EXPLAIN 时。 MySQL 表示它将从总共 500 万条记录中读取超过 40 万条记录。

那么我应该索引大陆列还是在这种情况下没有帮助?

这是解释结果

id = 1; select_type = SIMPLE; table = data; possible_keys = user_id; key = user_id; ref = NULL; rows = 582; Extra = Using where, Using filesort

【问题讨论】:

  • 为什么在 HAVING 子句中有这个?
  • HAVING 子句是后来被删除的GROUP BY 子句的剩余部分吗? || 是布尔值 OR 还是字符串连接? continent 是否已编入索引?你忘了发布解释计划。
  • 大陆未编入索引。这就是我想知道的。 HAVING 是 GROUP BY 的扩展

标签: mysql select indexing having


【解决方案1】:

首先,您的查询可能是错误的。当你在 where 或 having 子句或任何地方使用 ORAND 混合使用时,你应该使用括号。

其次,在您的情况下使用 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

【讨论】:

  • 谢谢@tomboom。这是解释id = 1 select_type = SIMPLE table = data possible_keys = user_id key = user_id ref = NULL rows = 582 Extra = Using where, Using filesort的结果
  • 另外,为了更好的可读性,您可以使用\G 而不是; 结束语句。然后列变成行,更容易发布。
  • @RayZ 也不要忘记SHOW CREATE TABLE data 并发布结果。
  • 您的解释计划说,user_id 上的索引已被使用。您可以尝试(除了在大陆上添加另一个索引)是两列(user_id,大陆)的复合索引。
  • 在 localhost 上,我能够在 20 毫秒内获取 582 行。所以我不相信在大陆上添加索引会有所帮助。再次感谢@tomoom。你真的帮助我从我的查询中消除了HAVING
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多