mysql - 按年度范围分组

时间:2011-02-14 18:05:52

标签: mysql

我需要按出生日期的年份分组。这就是我到目前为止所做的。如果您使用500000条记录运行存储过程,然后我写的查询您将看到大约需要25秒。我该如何改进呢?

create table people(
id int not null auto_increment primary key,
`dob` date
);

delimiter //
drop procedure if exists date_random //
create procedure date_random(in low date,in upp date,in number int)
begin
declare i int default 0;
while i < number do
    begin
    insert into people (`dob`)  values ( low + interval rand()* datediff(upp,low) day  );
    set i = i + 1;
    end;
end while;
end //
delimiter ;

call date_random('1910-01-01',curdate(),500000);


delimiter // 
create function `age`(dob date) returns int(11)
no sql
begin
return (year(curdate())-year(dob))-(right(curdate(),5)< right(dob,5) );
end //

delimiter ;


explain select sql_no_cache
concat_ws('-',min(age(dob)),max(age(dob))) as years,
count(*) as total
from people
group by if(age(dob)=0,1,ceil(age(dob)/5))

这是解释

的输出
+----+-------------+--------+-------+---------------+------+---------+------+--------+----------------------------------------------+
| id | select_type | table  | type  | possible_keys | key  | key_len | ref  | rows   | Extra                                        |
+----+-------------+--------+-------+---------------+------+---------+------+--------+----------------------------------------------+
|  1 | SIMPLE      | people | index | NULL          | ip   | 4       | NULL | 500000 | Using index; Using temporary; Using filesort |
+----+-------------+--------+-------+---------------+------+---------+------+--------+----------------------------------------------+
1 row in set (0.00 sec)

1 个答案:

答案 0 :(得分:1)

您的'年龄'功能可能更有效。而不是强制mysql将日期转换为字符串,做子串,比较它们,然后转换为最后一个减法的数字,(year(now()) - year(dob)) - (dayofyear(now()) < dayofyear(dob))怎么样 - 保持全部数字并消除至少一层铸造。

同样,由于它使用本机日期/时间函数,因此增加了MySQL在dob列上使用索引的可能性。您的当前方法无法使用索引处理,因为您在查询时动态地从日期字段派生文本值。