mysql 重构同步老数据_MySQL 重构查询的方式
主題:如何重構(gòu)查詢冰戰(zhàn)士何時需要使用這種技巧
(1)一種復(fù)雜查詢還是多個簡單查詢
設(shè)計查詢的時候需要考慮的一個重要問題是是否需要將一個復(fù)雜的查詢分成多個簡單的查詢。在平時我們總是強(qiáng)調(diào)需要數(shù)據(jù)庫完成盡可能多的工作,這樣做的邏輯在于以前總是認(rèn)為通絡(luò)通信,查詢解析以及優(yōu)化師一種代價很高的事情。但是MySQL在設(shè)計上讓連接和斷開連接都很輕量級,在返回一個小的查詢結(jié)果方面很高效。線代的網(wǎng)絡(luò)速度比以前要快很多,無論是帶寬還是延遲。
MySQL內(nèi)部內(nèi)部每秒能夠掃描內(nèi)存中上百萬行的數(shù)據(jù),相比之下MySQL響應(yīng)數(shù)據(jù)給客戶端就要慢很多了。在其他條件相同的時候,使用盡可能少的查詢當(dāng)然是更好的。但是,將一個大查詢分解成小查詢是很有必要的。不過再應(yīng)用設(shè)計的時候,如果一個查詢能夠勝任時還寫成多個小查詢那就是傻逼
(2)切分查詢
有時候?qū)τ谝粋€大查詢我們就要將大查詢切分成小查詢,每個查詢功能完全一樣,但是只完成一小部分,每次返回一小部分查詢結(jié)果。
刪除舊數(shù)據(jù)就是一個很好的例子。定期的清除大量數(shù)據(jù)時,如果用一個大語句一次性完成的話,則可能需要一次鎖住很多的數(shù)據(jù),占滿整個事務(wù)日志、耗盡系統(tǒng)資源、阻塞很多小的但重要的查詢。將一個大的DELETE語句切分成多個較小的查詢盡可能小的影響MySQL性能,同時還減少M(fèi)ySQL復(fù)制到延遲。同時,需要注意的是,如果每次刪除數(shù)據(jù)后,都暫停一會兒再做下一次殺出,這樣也可以將服務(wù)器上原本一次性的壓力分散到一個很長的時間段中,就可以大大的降低對服務(wù)器的影響,還可以大大減少刪除時鎖的持有時間
(3)分解關(guān)聯(lián)查詢
簡單的關(guān)聯(lián)查詢分解就是可以對每個表進(jìn)行一次單表查詢,然后將結(jié)果在應(yīng)用程序中進(jìn)行關(guān)聯(lián)。例如:
select * fromtag
join tag_post ON tag_post.tag_id=tag.id
join post ON tag_post_id=post.idwhere tag.tag='mysql'
可以分解成
select * from tag where tag='mysql'
select * from tag_post where tag_id=1234
select * from post where post.id in (123,456,567,9098,8904)
乍一看,這樣做并沒有什么好處,原本一條查詢,這里卻變成多條查詢,返回的結(jié)果又是一模一樣。事實(shí)上,用分解關(guān)聯(lián)查詢重構(gòu)查詢有如下的優(yōu)點(diǎn):
①讓緩存的效率更高。②將查詢費(fèi)恩節(jié)后,執(zhí)行單個查詢可以減少鎖競爭。③在應(yīng)用層做關(guān)聯(lián),可以更容易對數(shù)據(jù)庫進(jìn)行拆分,更容易做到高性能和可拓展。④查詢本身效率也可能有所提升。⑤可以減少冗余記錄的查詢。⑥更進(jìn)一步,這樣做相當(dāng)于在應(yīng)用中實(shí)現(xiàn)了哈希關(guān)聯(lián),而不是使用MySQL的嵌套循環(huán)關(guān)聯(lián)
在很多情況下,通過重構(gòu)查詢將關(guān)聯(lián)放到應(yīng)用程序中將會更加高效,這樣的場景有很多。比如:當(dāng)應(yīng)用能夠方便的緩存單個查詢的 結(jié)果的時候、當(dāng)可以將數(shù)據(jù)分布到不同的MySQL服務(wù)器上的時候、當(dāng)能夠使用IN代替關(guān)聯(lián)查詢的時候。
總結(jié)
以上是生活随笔為你收集整理的mysql 重构同步老数据_MySQL 重构查询的方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 线程休眠_百战程序员:java
- 下一篇: mysql 实时聚合分析_mysql滑动