我正在尝试分解并重新编写一个由已经过时的开发人员创建的视图。查询需要三个以上的分钟才能访问,我假设来自所有的CONCAT。
CREATE VIEW `active_users_over_time` AS
select
`users_activity`.`date` AS `date`,
time_format(
addtime(
concat(`users_activity`.`date`,' ',`users_activity`.`time`),
concat('0 ',sec_to_time(`users_activity`.`duration_checkout`),'.0')
),'%H:%i:%s') AS `time`,
`users_activity`.`username` AS `username`,
count(addtime(concat(`users_activity`.`date`,' ',`users_activity`.`time`),
concat('0 ',sec_to_time(`users_activity`.`duration_checkout`),'.0'))) AS `checkouts`
from `users_activity`
group by
concat(
addtime(
concat(`users_activity`.`date`,' ',`users_activity`.`time`),
concat('0 ',sec_to_time(`users_activity`.`duration_checkout`),'.0')
),
`users_activity`.`username`);
数据来自SQL表:
CREATE TABLE `users_activity` (
`id` int(10) unsigned NOT NULL auto_increment,
`featureid` smallint(5) unsigned NOT NULL,
`date` date NOT NULL,
`time` time NOT NULL,
`duration_checkout` int unsigned NOT NULL,
`update_date` date NOT NULL,
`username` varchar(255) NOT NULL,
`checkout` smallint(5) unsigned NOT NULL,
`licid` smallint(5) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `featureid_licid_username` (`featureid`,`licid`,`date`,`time`,`username`),
FOREIGN KEY(featureid) REFERENCES features(id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
我很难确定究竟需要什么以及什么不需要。
有人有什么想法吗?感谢。
答案 0 :(得分:2)
我认为这会完成原始查询的所有操作,跳过一堆冗余步骤:
select `date`
, `time`
, `username`
, count(1) as `checkouts`
from
(
select
`users_activity`.`date` AS `date`
,time_format(
addtime(`users_activity`.`date`,`users_activity`.`time`)
+ interval `users_activity`.`duration_checkout` second
,'%H:%i:%s'
) AS `time`
,`users_activity`.`username` AS `username`
from `users_activity`
) x
group by `username`, `date`, `time`
您可能还想查看表中的索引以查看是否可以在其他位置进行优化(例如,如果您还没有关于用户名和日期字段的索引,那么您将获得很多好处这个查询通过添加一个)。
答案 1 :(得分:-2)
您可以从重写GROUP BY clase开始:
group by
concat(
addtime(
concat(`users_activity`.`date`,' ',`users_activity`.`time`),
concat('0 ',sec_to_time(`users_activity`.`duration_checkout`),'.0')
),
`users_activity`.`username`);
到这一个:
GROUP BY `users_activity`.`date`,
`users_activity`.`time`,
`users_activity`.`duration_checkout`,
`users_activity`.`username`
此更改应该可以稍微节省将日期转换为字符串并将其连接起来,并且查询结果不应更改。
然后,您可以考虑在GROUP BY列上创建复合索引
根据此链接:http://dev.mysql.com/doc/refman/5.0/en/group-by-optimization.html
使用GROUP BY索引的最重要前提条件是所有GROUP BY列引用同一索引的属性
这意味着,如果我们创建以下索引:
CREATE INDEX idx_name ON `users_activity`(
`date`,`time`,`duration_checkout`,`username`
);
然后MySql可能会使用它来优化GROUP BY(但不能保证)。