mysql join+order by view 优化

收获

一种思路,在写少查多(或者查询复杂)的情况下,使用mysql 物化表解决查询慢的情况。

背景

这是以前的一个遗留项目,需要修改的模块的逻辑的功能是从一个视图中进行查询。视图为T1,T2,T3三个表进行inner join的结果。三个表中t1为驱动表,t2和t3在关联的字段上均有索引,t1的记录条数是最少的。

问题

这次要新增一个功能是,筛选结果需要再根据t2表的一个int类型和一个data类型的字段进行排序。

由上面的项目背景可知,视图中的inner join已经经过了优化,速度上还是可以满足客户的要求的,但仍然会达到三-四秒的时间,再增加排序,时间会更长,在解决思路1中,时长达到了45s。

解决思路

朴素的解决思路1:

直接在视图中修改,将在生成视图的语句后面加上order by t2.int,t2.date.

结果:视图超级慢,需要经过45s才能查询出来。

原因:inner join 之后,是在内存中形成了临时表,然后根据临时表进行order by,由于临时表是没有索引的,order by 使用file-sort进行排序,所以耗时非常慢,无法达到需求目标。

解决思路2:

2 将t2表中的那两个排序字段,加上索引之后,将t2进行排序,然后T2表作为驱动表,去连接T1,T3表,(由于mysql视图不支持子查询,所以T2表排序必须做成一个视图)

结果:还是很慢,21秒

原因:T2表太大了,连接表会很慢。

解决思路3:

以空间换时间的思路,将视图物化。

由于mysql不支持物化视图,必须自己写触发器实现mysql的物化视图,然后再加索引

步骤:

1 创建物化表:create table table_for_view select * from view;

2 在这个表的各个关联表(有可能做修改的表)写触发器,在更新各个关联表的过程中,触发器会实时更新相应的物化表。

按照这个思路解决了问题,查询时间在0.1秒以下了。

猜你喜欢

转载自blog.csdn.net/whodarewin2005/article/details/18182087
今日推荐