用STRAIGHT_JOIN优化mysql的执行速度

优化sql的执行速度,我们通常需要查看EXPLAIN的结果,没有使用索引的加上索引,索引使用不对的也可以强制使用某个索引,但是有些情况下,这2招都不管用,是sql内部的执行顺序不正确,导致速度很慢。

执行顺序通常是mysql内部优化器根据表预测的大小,索引等等情况自动判断的,但是某些情况下会判断错误,这个时候我们就需要调整执行顺序。

mysql8.0以上有优化器提示(Optimizer Hints),可以详细控制优化器的执行顺序,比较复杂。但是生产环境是5.6,无法使用。

8.0以下可以使用STRAIGHT_JOIN 来调整执行顺序,用法也比较简单,用STRAIGHT_JOIN 来代替JOIN就可以了,mysql会按照书写的顺序从左到右执行,这样我们就控制了mysql执行顺序。

下面我们来看一个具体的例子,有4个表INNER JOIN连接,还有一个EXISTS条件

	SELECT
		*
	FROM
		mm_detail a
		INNER JOIN  mm_domain d ON d.DOMAIN=a.DOMAIN
		INNER JOIN  mm_media c ON c.DOMAIN_ID=d.DOMAIN_ID
		INNER JOIN  mm_url x ON x.MEDIA_ID=c.MEDIA_ID
	WHERE
		a.URL_TYPE=1
		AND NOT EXISTS(SELECT 1 FROM mm_detail y WHERE y.URL_TYPE=3 AND y.URL_UNIQUE=x.URL_UNIQUE AND y.GROUP_NO=a.GROUP_NO)

由于数据量比较大,上面这个sql要执行几个小时以上,具体是几个小时不知道,没有耐心等待

 

idselect_typetabletypepoosible_keyskeykey_kenrefrowsExtra
1PRIMARYxALLmedia_id   238426Using where
1PRIMARYceq_refPRIMARY,DOMAIN_IDPRIMARY8media.x.MEDIA_ID1 
1PRIMARYdeq_refPRIMARY,domainPRIMARY4media.c.DOMAIN_ID1 
1PRIMARYarefIDX_SEARCH,IDX_DOMAIN,IDX_URL_TYPEIDX_DOMAIN768media.d.DOMAIN26Using index condition; Using where
2DEPENDENT SUBQUERYyrefIDX_SEARCH,IDX_GROUP_NO,IDX_URL_TYPE,IDX_URL_UNIQUEIDX_SEARCH2111const,media.a.GROUP_NO,media.x.URL_UNIQUE1Using index

从EXPLAIN的结果可以看到执行顺序,先执行了包含EXISTS的x表,并且是遍历全表,由于x表数据量最大,导致非常慢,这个执行顺序显然是错误的

下面我用STRAIGHT_JOIN  代替 INNER JOIN,强制查询顺序,执行时间变成21秒,差距非常大

 

	SELECT
		*
	FROM
		mm_detail a
		STRAIGHT_JOIN  mm_domain d ON d.DOMAIN=a.DOMAIN
		STRAIGHT_JOIN  mm_media c ON c.DOMAIN_ID=d.DOMAIN_ID
		STRAIGHT_JOIN  mm_url x ON x.MEDIA_ID=c.MEDIA_ID
	WHERE
		a.URL_TYPE=1
		AND NOT EXISTS(SELECT 1 FROM mm_detail y WHERE y.URL_TYPE=3 AND y.URL_UNIQUE=x.URL_UNIQUE AND y.GROUP_NO=a.GROUP_NO)

 

idselect_typetabletypepoosible_keyskeykey_kenrefrowsExtra
1PRIMARYarefIDX_SEARCH,IDX_DOMAIN,IDX_URL_TYPEIDX_SEARCH4const223000Using where
1PRIMARYdeq_refPRIMARY,domaindomain302media.a.DOMAIN1Using index condition
1PRIMARYcrefPRIMARY,DOMAIN_IDDOMAIN_ID4media.d.DOMAIN_ID2 
1PRIMARYxrefmedia_idmedia_id9media.c.MEDIA_ID264Using where
2DEPENDENT SUBQUERYyrefIDX_SEARCH,IDX_GROUP_NO,IDX_URL_TYPE,IDX_URL_UNIQUEIDX_SEARCH2111const,media.a.GROUP_NO,media.x.URL_UNIQUE1Using index

从EXPLAIN的结果我们看到,执行顺序按照sql的书写顺序,都使用了索引,这个就是速度变快的原因。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值