table_1有10万条记录
索引为只有A,
执行以下sql1
select count(A) ,B from table_1 group by B
运行时间10秒以上
执行以下sql2
select sum(case when c ="1" and d = "1" then 0 else 1),
 sum(case when c ="2" and d = "1" then 0 else 1),
 sum(case when d = "2" then 0 else 1),
sum(case when d = "3" or d="4" then 0 else 1)
 from table_1
执行速度5秒以上问题:sql1 是否需要给B加索引,如果B为日期类型,加索引有什么负面影响。
sql2 可以优化么?

解决方案 »

  1.   

    1.sql1是按B来进行分组,所以首先应该对B来加索引.2.sql2优化的范围就比较小了.但是你可以在c,d字段上建立组合索引,这样只需要扫描索引就可以得到你需要的结果了.可以试试!比较前后的速度.
      

  2.   

    用explain SQL 分析一下,你所要执行的SQL到底做了些什么,即它检查了多少行记录,有没有使用到你所建的索引,才得到你想要结果.
    如果确定没有使用索引,你就要考虑增加一个它执行SQL时可能使用的索引
      

  3.   

    to:mschen(Co-ok) 
    1.sql1 已经在B上加索引了,速度还可以。2.sql2 没用过组合索引,可以试试
      

  4.   

    sql2  
    考虑 使用别的方法来实现。比如 考虑使用 select count(*)考虑分拆为四个 sql 来实现。你可以测试一下,修改后的效率。
      

  5.   

    sql1,  如果B 为日期型的,不会影响效率,Mysql 会将日期型转化为整型来对待,效率不会降低。
    sql2, 如果使用的是  5.0 可以使用如下的sql 语句,
    SQL_B:  select * from(
    (select count(*) from a ) as total,
    (select count(*) from a where c = 1 and d = 1) as a,
    (select count(*) from a where c =2 and d = 1) as b,
    (select count(*) from a where d =2 ) as c,
    (select count(*) from a where d != 4 and d !=3 ) as d)当然 select 出来的并不是你要的结果需要经过计算下就可以了,相对来说效率会高点。或者换成 
    SQL_C:   select sum(if(c ="1" and d = "1",0,1)) as aa,
     sum( if(c ="2" and d = "1",0, 1)) as bb,
     sum(if(d = "2",0 ,1)) as cc,
     sum(if(d != "3" and d !="4",1,0)) as dd
     from a
    似乎效率也会高点。
    SQL_B:  执行时间为 :  0.14s
    SQL_C:  执行时间为:   0.27s
    原SQL2  执行时间为:   0.28s测试是在 Windows XP 上,内存1G 双核 1.83Hz,mysql 5.0
    测试表:
    create table a (
     id int(11) not null auto_increment,
    b int(11) default 0,
    c int(11) default 0,
    d int(11) default 0,
    primary key (id),
    key idx (c,d),
    key idx_2(d)
    ) engine=myisam default charset=latin1;记录数:  102925