为什么WHERE IN会非常慢

时间:2013-04-16 09:47:41

标签: mysql search

我已经使用了以下查询一段时间了,但随着结果数据库的增长,它变得越来越不可用。有人可以提出另一种方法吗?

我在c.name和r.scope上有全文索引

SELECT * FROM results r 
        INNER JOIN categories c on r.id = c.result_id 
        INNER JOIN tags t on r.id = t.result_id 
        WHERE c.name in ('purchase', 'single_family', 'other')

        AND ( r.scope = 'all' OR r.scope = 'hi' )
        AND published = 1
    GROUP BY r.id
        HAVING COUNT(c.c_id) >= 3
        ORDER BY r.usefulness DESC
        LIMIT 8 OFFSET 0

非常感谢任何帮助。谢谢!

编辑:这是EXPLAIN的结果

  id    select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  c   range   nameindex,name  nameindex   767     NULL    10036   Using where; Using temporary; Using filesort
1   SIMPLE  t   ALL     NULL    NULL    NULL    NULL    10229   Using where; Using join buffer
1   SIMPLE  r   eq_ref  PRIMARY,scope   PRIMARY     4   rfw.t.result_id     1   Using where

4 个答案:

答案 0 :(得分:1)

更新:查询以创建索引

CREATE INDEX name ON categories(name);


使用Explain语句,explain的输出将帮助您确定哪个列需要索引&其他有用的信息。

mysql doc中所述:

  

当您在SELECT语句之前使用关键字EXPLAIN,MySQL时   显示优化程序中有关查询执行的信息   计划。也就是说,MySQL解释了如何处理语句,   包括有关表如何连接以及以何种顺序的信息。

运行:

    EXPLAIN SELECT * FROM results r 
    INNER JOIN categories c on r.id = c.result_id 
    INNER JOIN tags t on r.id = t.result_id 
    WHERE c.name in ('purchase', 'single_family', 'other')

    AND ( r.scope = 'all' OR r.scope = 'hi' )
    AND published = 1
GROUP BY r.id
    HAVING COUNT(c.c_id) >= 3
    ORDER BY r.usefulness DESC
    LIMIT 8 OFFSET 0

答案 1 :(得分:0)

此处您不需要fulltext索引;一个常规索引是mySQL想要用于该字段的。

全文索引旨在用于全文搜索(即MATCH .. AGAINST查询);它与简单的等号或IN ()查询无关。

答案 2 :(得分:0)

如果您想让查询更快,可以做三件事:

  • c.name上添加索引(慢查询表明您没有)
  • count添加到categories(带有索引),其中包含缓存数据
    WHERE c.count >= 3只会获得有限数量的结果 HAVING COUNT() >= 3必须在返回
  • 之前获取所有结果 如果可能,
  • 使用WHERE c.id IN (...)代替WHERE c.name in ('...) ...
    id = identification = PRIMARY KEY,这就是它的意图

答案 3 :(得分:-1)

1)仅选择答案列所需。 2)设置属性表索引。 您也可以使用EXPLAIN SELECT ...

获取一些信息