2009-07-08 76 views
1

我正在尝试优化需要相当一段时间的MYSQL语句。这个表运行的表是600k +,查询超过10秒。Mysql优化

SELECT DATE_FORMAT(timestamp, '%Y-%m-%d') AS date, COUNT(DISTINCT (
email 
)) AS count 
FROM log 
WHERE timestamp > '2009-02-23' 
AND timestamp < '2020-01-01' 
AND TYPE = 'play' 
GROUP BY date 
ORDER BY date DESC 

我只是索引时间戳和类型,还有一个timestamp_type(type_2)。

这里是解释结果,这个问题似乎是一个文件排序,但我不知道如何解决这个问题?

id: 1 
select_type: SIMPLE 
table: log 
type: ref 
possible_keys: type,timestamp,type_2 
key: type_2 
key_len: 1 
ref: const 
rows: 226403 
Extra: Using where; Using filesort 

感谢

+0

你能表现出与SQL代码的当前indexe定义,因此没有关于他们是如何设置的怀疑。 另外,我们在谈论什么数据量? (有多少行,多少个“TYPE”,每个TYPE和时间戳有多少行?) – Brimstedt 2009-07-08 11:08:09

回答

4

事情尝试:

  • 有一个单独的date列(索引)并使用它,而不是你timestamp
  • 添加一个索引跨typedate
  • 利用之间(不认为这会影响速度,但它更易于阅读)

所以最好你会

  1. 创建date柱上,用UPDATE table SET date = DATE(timestamp)填充
  2. 指数跨越typedate
  3. 将您的选择更改为... type =?和日期之间?和?
+0

这是一个很好的建议 - 很明显,不要把你的专栏称为'日期'。 – Fenton 2009-07-08 10:45:25

0

尝试重写以先在TYPE上过滤。然后应用您的日期范围和汇总。基本上创建一个内联视图,用于过滤掉类型。我知道优化器可能已经这样做了,但是当试图提高性能时,我发现确定首先发生的事情会很有帮助。

0
  1. DATE_FORMAT不会使用索引。

  2. 仍然可以使用下面的查询来利用索引上时间戳列

    SELECT时间戳作为日期,COUNT(DISTINCT( 电子邮件 ))AS计数 FROM登录 其中timestamp> '2009-02-23 00:00:00' 和时间戳< '2020年1月1日23:59:59' 和type = '玩' GROUP BY日期 ORDER BY日期DESC

  3. 格式打印时的日期时间值日期/使用