【问题标题】:Mysql Query Improve PerformanceMysql 查询提高性能
【发布时间】:2011-12-03 00:48:50
【问题描述】:

我有以下查询:

SELECT COUNT(sid),fDate,COUNT(DISTINCT(cid)) 
    FROM forwarding  
    WHERE fDate BETWEEN "2011-06-01" AND "2011-06-30" 
    GROUP BY fDate

解释给我以下输出:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  forwarding  index   fDate,fDate_2   fDate_2 3       1481127 Using where

可以看到有很多数据。 总工作时间为 12 秒。 我怎样才能提高性能?我不知道在设置索引时我还能做些什么。

这个表有我的索引:

fDate (fDate, f_shop)
fDate2(dDate),
f_shop(f_shop)

感谢您的帮助。

更新:

现在我在 where 子句中添加了一列,查询比以前慢了很多。

SELECT COUNT(sid),fDate,COUNT(DISTINCT(cid)) FROM forwarding 
WHERE fDate BETWEEN "2011-06-01" AND "2011-06-30"  AND f_shop=10077 GROUP BY fDate

我在 forwardDate 和 f_shop 上有一个索引,但性能很慢。什么是完美的解决方案? 谢谢

【问题讨论】:

  • 如果sid不能是NULL,使用COUNT(*)而不是COUNT(sid)
  • 还有一个问题:fDateDATE 类型还是 DATETIME 类型?
  • fDate 是一个日期类型。我会尝试其他技巧。谢谢
  • 注意(例如)WHERE fDate BETWEEN '2011-06-01' AND '2011-06-02' 的查询使用了一些索引,但你的没有,你不能做太多。 MySQL 决定(通常是正确的!)最好使用任何索引,而是使用表的完整扫描(很大)部分。
  • (fDate, cid) 索引之所以有效,是因为您拥有 DISTINCT cid。您的查询必须为每个fDate 查找有多少不同的cid 存在。如果它可以使用索引来完成(无需从表中读取任何数据),则比扫描整个表要快。

标签: php mysql indexing


【解决方案1】:

除了 ypercube 提供的答案之外,您在哪里寻找特定商店的查询...我会有一个索引

(f_shop, fdate, cid) 以确保索引的所有 3 个部分都使用前面的最小 WHERE 子句限定符。在您的上一个示例中,您已经包含了对特定商店的兴趣...

SELECT 
      COUNT(sid),
      fDate,
      COUNT(DISTINCT(cid)) 
   FROM 
      forwarding 
   WHERE 
          f_shop=10077 
      AND fDate BETWEEN "2011-06-01" AND "2011-06-30"
   GROUP BY 
      fDate

【讨论】:

  • 是的,非常感谢。顺序对索引重要吗?我怎么知道 fDate 和 f_shop 不够用?
  • @user954740,是的,顺序很重要,并且应该按照您尝试根据常见查询找到的最细粒度的部分的顺序。在这种情况下,我会假设 F_SHOP 因为你可以有 100+ F_SHOP 条目。因此,首先按日期范围扫描,您仍然会跳过所有其他“商店”。通过将它放在第一位,您从一家商店开始,然后在此范围内,只有您关注的日期范围。
【解决方案2】:

How MySQL Uses Indexes 回答了我迄今为止关于 MySQL 索引的所有问题。可能值得一读。

【讨论】:

    猜你喜欢
    • 2023-04-08
    • 1970-01-01
    • 2023-03-14
    • 2016-08-18
    • 1970-01-01
    • 2013-03-21
    • 2013-03-28
    • 2019-09-16
    • 1970-01-01
    相关资源
    最近更新 更多