我有一个查询,需要更多的时间来执行。我试着优化它。GROUP BY中的一些函数可能会增加查询时间。所以我正在努力找出如何优化这部分。
我正在使用Mysql 5.5.17 .
我不能使用强制索引,因为我正在使用Hibernate,所以这是不可选的。
我有一些其他的选项,如:
1)使用别名来代替group by中的concat(…)
2)或将concat()替换为其中的列。
示例:group by concat(1,2,3.) => group by 1,2,3
在尝试了以上两个选项后,我没有看到"查询成本"有任何差异
查询看起来像这样(表名改变了):
select sum(this_.a + this_.b + this_.c + this_.d + this_.e +
this_.f + this_.g + this_.h + this_.i + this_.j) as sent,
sum(this_.a + this_.b + this_.c + this_.d + this_.e) as delivered,
d2_.name as y2_, d2_.id as y3_, concat(cast(b4_.id as char),
'.',c1_.name,'.',cs5_.name,'_',date_format(b4_.createddate,
'%Y-%b-%d %H:%i:%s')
) as allias_concat, b4_.id as y5_,
this_.year as y6_, this_.month as y7_, this_.day as y8_,
this_.weekday as y9_, this_.weekofmonth as y10_,
this_.bltid as y11_,
b4_.id as y12_, c1_.name as y13_,
cs5_.name as y14_, b4_.createddate as y15_,
cs5_.subject as y16_, d2_.name as y17_
from TABLE1 this_
inner join TABLE2 c1_ on this_.cgnid=c1_.id
inner join TABLE3 b4_ on this_.bltid=b4_.id
inner join TABLE4 csc6_ on b4_.schdlid=csc6_.id
inner join TABLE5 cs5_ on this_.constid=cs5_.id
left outer join TABLE6 f3_ on this_.fid=f3_.id
inner join TABLE7 d2_ on this_.dptid=d2_.id
where (f3_.name<>'TRASH'
or c1_.fid=0
)
and c1_.status<>'K'
and d2_.id in (1)
and ((b4_.createddate between '2015-02-01 10:30:00'
AND '2015-05-13 10:29:59'
and csc6_.isrealtime = 'N'
)
or (csc6_.isrealtime = 'Y'
and this_.bltdate between '2015-02-01 10:30:00'
AND '2015-05-13 10:29:59')
)
group by d2_.id,
concat(cast(b4_.id as char),'.',c1_.name,'.',cs5_.name,'_',
date_format(b4_.createddate,'%Y-%b-%d %H:%i:%s')
),
b4_.id,
this_.year, this_.month, this_.day,
this_.bltid
limit 20001
请建议…
对不起,这将是一个"反答案"…
闻起来像"过度正常化"。例如,感觉b4_
是日期时间(createddate
)的规范化,而不是其他。这是正确的吗?如果是这样,那就增加了复杂性,减慢了WHERE
和GROUP BY
的速度,并且消除了一些优化的可能性。
"函数"不是问题所在。由于GROUP BY
中的项来自不同的表,因此没有方法来优化它。GROUP BY
必须从各个表中收集信息,将它们放入临时表中,对其进行排序,然后扫描它。(或者类似的东西。关键是没有捷径。
"我不能使用…因为我正在使用Hibernate"——这是另一个第三方软件"碍事"的例子。如果你不能更改查询,我们无法帮助你。