日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

stright 在mysql_MySQL优化的奇技淫巧之STRAIGHT_JOIN

發(fā)布時間:2023/12/15 数据库 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 stright 在mysql_MySQL优化的奇技淫巧之STRAIGHT_JOIN 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

最近沒怎么搞SQL優(yōu)化,碰巧數(shù)據(jù)庫被慢查詢搞掛了,于是拿來練練手。

問題

通過「SHOW FULL PROCESSLIST」語句很容易就能查到問題SQL,如下:

SELECT post.*

FROM post

INNER JOIN post_tag ON post.id = post_tag.post_id

WHERE post.status = 1 AND post_tag.tag_id = 123

ORDER BY post.created DESC

LIMIT 100

說明:因為post和tag是多對多的關(guān)系,所以存在一個關(guān)聯(lián)表post_tag。

試著用EXPLAIN查詢一下SQL執(zhí)行計劃(篇幅所限,結(jié)果有刪減):

+----------+---------+-------+-----------------------------+

| table | key | rows | Extra |

+----------+---------+-------+-----------------------------+

| post_tag | tag_id | 71220 | Using where; Using filesort |

| post | PRIMARY | 1 | Using where |

+----------+---------+-------+-----------------------------+

下面給出優(yōu)化后的SQL,唯一的變化就是把連接方式改成了「STRAIGHT_JOIN」:

SELECT post.*

FROM post

STRAIGHT_JOIN post_tag ON post.id = post_tag.post_id

WHERE post.status = 1 AND post_tag.tag_id = 123

ORDER BY post.created DESC

LIMIT 100

試著用EXPLAIN查詢一下SQL執(zhí)行計劃(篇幅所限,結(jié)果有刪減):

+----------+----------------+--------+-------------+

| table | key | rows | Extra |

+----------+----------------+--------+-------------+

| post | status_created | 119340 | Using where |

| post_tag | post_id | 1 | Using where |

+----------+----------------+--------+-------------+

對比優(yōu)化前后兩次EXPLAIN的結(jié)果來看,優(yōu)化后的SQL雖然「rows」更大了,但是沒有了「Using filesort」,綜合來看,性能依然得到了提升。

提醒:注意兩次EXPLAIN結(jié)果中各個表出現(xiàn)的先后順序,稍后會解釋。

解釋

對第一條SQL而言,為什么MySQL優(yōu)化器選擇了一個耗時的執(zhí)行方案?對第二條SQL而言,為什么把連接方式改成STRAIGHT_JOIN之后就提升了性能?

這一切還得從MySQL對多表連接的處理方式說起,首先MySQL優(yōu)化器要確定以誰為驅(qū)動表,也就是說以哪個表為基準(zhǔn),在處理此類問題時,MySQL優(yōu)化器采用了簡單粗暴的解決方法:哪個表的結(jié)果集小,就以哪個表為驅(qū)動表,當(dāng)然MySQL優(yōu)化器實(shí)際的處理方式會復(fù)雜許多,具體可以參考:MySQL優(yōu)化器如何選擇索引和JOIN順序。

說明:在EXPLAIN結(jié)果中,第一行出現(xiàn)的表就是驅(qū)動表。

繼續(xù)post連接post_tag的例子,MySQL優(yōu)化器有如下兩個選擇,分別是:

以post為驅(qū)動表,通過status_created索引過濾,結(jié)果集119340行

以post_tag為驅(qū)動表,通過tag_id索引過濾,結(jié)果集71220行

顯而易見,post_tag過濾的結(jié)果集更小,所以MySQL優(yōu)化器選擇它作為驅(qū)動表,可悲催的是我們還需要以post表中的created字段來排序,也就是說排序字段不在驅(qū)動表里,于是乎不可避免的出現(xiàn)了「Using filesort」,甚至「Using temporary」。

知道了來龍去脈,優(yōu)化起來就容易了,要盡可能的保證排序字段在驅(qū)動表中,所以必須以post為驅(qū)動表,于是乎必須借助「STRAIGHT_JOIN」強(qiáng)制連接順序。

實(shí)際上在某些特殊情況里,排序字段可以不在驅(qū)動表里,比如驅(qū)動表結(jié)果集只有一行記錄,并且在連接其它表時,索引除了連接字段,還包含了排序字段,此時連接表后,索引中的數(shù)據(jù)本身自然就是排好序的。

既然聊到這里順帶說點(diǎn)題外話,大家可能會遇到類似下面的問題:原本運(yùn)行良好的查詢語句,過了一段時間后,可能會突然變得很糟糕。一個很大可能的原因就是數(shù)據(jù)分布情況發(fā)生了變化,從而導(dǎo)致MySQL優(yōu)化器對驅(qū)動表的選擇發(fā)生了變化,進(jìn)而出現(xiàn)索引失效的情況,所以沒事最好多查查,關(guān)注一下這些情況。

對于「STRAIGHT_JOIN」,我總覺得這種非標(biāo)準(zhǔn)的語法屬于奇技淫巧的范疇,能不用盡量不用,畢竟多數(shù)情況下,MySQL優(yōu)化器都能做出正確的選擇。

總結(jié)

以上是生活随笔為你收集整理的stright 在mysql_MySQL优化的奇技淫巧之STRAIGHT_JOIN的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。