就是sql查詢優(yōu)化唄。
創(chuàng)新互聯(lián)公司2013年開創(chuàng)至今,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元宜章做網(wǎng)站,已為上家服務(wù),為宜章各地企業(yè)和個人服務(wù),聯(lián)系電話:18980820575
在不是服務(wù)器性能影響的時(shí)候,可以關(guān)注以下:
1、通過explain查看sql的執(zhí)行計(jì)劃,看是否用到了索引
2、是否sql寫的不合理,需要改寫sql等
3、還是sql沒有問題,索引也合理,就是數(shù)據(jù)太大,字段太多引起查詢慢,這個就可以考慮是不是改分表或者分開啥的。
優(yōu)化這一塊涉及到的比較多,可以多重網(wǎng)上,或者博客看看總結(jié),對比你的情況去優(yōu)化
問題
我們有一個 SQL,用于找到?jīng)]有主鍵 / 唯一鍵的表,但是在 MySQL 5.7 上運(yùn)行特別慢,怎么辦?
實(shí)驗(yàn)
我們搭建一個 MySQL 5.7 的環(huán)境,此處省略搭建步驟。
寫個簡單的腳本,制造一批帶主鍵和不帶主鍵的表:
執(zhí)行一下腳本:
現(xiàn)在執(zhí)行以下 SQL 看看效果:
...
執(zhí)行了 16.80s,感覺是非常慢了。
現(xiàn)在用一下 DBA 三板斧,看看執(zhí)行計(jì)劃:
感覺有點(diǎn)慘,由于 information_schema.columns 是元數(shù)據(jù)表,沒有必要的統(tǒng)計(jì)信息。
那我們來 show warnings 看看 MySQL 改寫后的 SQL:
我們格式化一下 SQL:
可以看到 MySQL 將
select from A where A.x not in (select x from B) //非關(guān)聯(lián)子查詢
轉(zhuǎn)換成了
select from A where not exists (select 1 from B where B.x = a.x) //關(guān)聯(lián)子查詢
如果我們自己是 MySQL,在執(zhí)行非關(guān)聯(lián)子查詢時(shí),可以使用很簡單的策略:
select from A where A.x not in (select x from B where ...) //非關(guān)聯(lián)子查詢:1. 掃描 B 表中的所有記錄,找到滿足條件的記錄,存放在臨時(shí)表 C 中,建好索引2. 掃描 A 表中的記錄,與臨時(shí)表 C 中的記錄進(jìn)行比對,直接在索引里比對,
而關(guān)聯(lián)子查詢就需要循環(huán)迭代:
select from A where not exists (select 1 from B where B.x = a.x and ...) //關(guān)聯(lián)子查詢掃描 A 表的每一條記錄 rA: ? ? 掃描 B 表,找到其中的第一條滿足 rA 條件的記錄。
顯然,關(guān)聯(lián)子查詢的掃描成本會高于非關(guān)聯(lián)子查詢。
我們希望 MySQL 能先"緩存"子查詢的結(jié)果(緩存這一步叫物化,MATERIALIZATION),但MySQL 認(rèn)為不緩存更快,我們就需要給予 MySQL 一定指導(dǎo)。
...
可以看到執(zhí)行時(shí)間變成了 0.67s。
整理
我們診斷的關(guān)鍵點(diǎn)如下:
\1. 對于 information_schema 中的元數(shù)據(jù)表,執(zhí)行計(jì)劃不能提供有效信息。
\2. 通過查看 MySQL 改寫后的 SQL,我們猜測了優(yōu)化器發(fā)生了誤判。
\3. 我們增加了 hint,指導(dǎo) MySQL 正確進(jìn)行優(yōu)化判斷。
但目前我們的實(shí)驗(yàn)僅限于猜測,猜中了萬事大吉,猜不中就無法做出好的診斷。
在已有的 MySQL 服務(wù)器之上使用 Apache Spark (無需將數(shù)據(jù)導(dǎo)出到 Spark 或者 Hadoop 平臺上),這樣至少可以提升 10 倍的查詢性能。使用多個 MySQL 服務(wù)器(復(fù)制或者 Percona XtraDB Cluster)可以讓我們在某些查詢上得到額外的性能提升。你也可以使用 Spark 的緩存功能來緩存整個 MySQL 查詢結(jié)果表。
思路很簡單:Spark 可以通過 JDBC 讀取 MySQL 上的數(shù)據(jù),也可以執(zhí)行 SQL 查詢,因此我們可以直接連接到 MySQL 并執(zhí)行查詢。那么為什么速度會快呢?對一些需要運(yùn)行很長時(shí)間的查詢(如報(bào)表或者BI),由于 Spark 是一個大規(guī)模并行系統(tǒng),因此查詢會非常的快。MySQL 只能為每一個查詢分配一個 CPU 核來處理,而 Spark 可以使用所有集群節(jié)點(diǎn)的所有核。在下面的例子中,我們會在 Spark 中執(zhí)行 MySQL 查詢,這個查詢速度比直接在 MySQL 上執(zhí)行速度要快 5 到 10 倍。
另外,Spark 可以增加“集群”級別的并行機(jī)制,在使用 MySQL 復(fù)制或者 Percona XtraDB Cluster 的情況下,Spark 可以把查詢變成一組更小的查詢(有點(diǎn)像使用了分區(qū)表時(shí)可以在每個分區(qū)都執(zhí)行一個查詢),然后在多個 Percona XtraDB Cluster 節(jié)點(diǎn)的多個從服務(wù)器上并行的執(zhí)行這些小查詢。最后它會使用map/reduce 方式將每個節(jié)點(diǎn)返回的結(jié)果聚合在一起形成完整的結(jié)果。
問題
我們有一個 SQL,用于找到?jīng)]有主鍵 / 唯一鍵的表,但是在 MySQL 5.7 上運(yùn)行特別慢,怎么辦?
實(shí)驗(yàn)
我們搭建一個 MySQL 5.7 的環(huán)境,此處省略搭建步驟。
寫個簡單的腳本,制造一批帶主鍵和不帶主鍵的表:
執(zhí)行一下腳本:
現(xiàn)在執(zhí)行以下 SQL 看看效果:
...
執(zhí)行了 16.80s,感覺是非常慢了。
現(xiàn)在用一下 DBA 三板斧,看看執(zhí)行計(jì)劃:
感覺有點(diǎn)慘,由于 information_schema.columns 是元數(shù)據(jù)表,沒有必要的統(tǒng)計(jì)信息。
那我們來 show warnings 看看 MySQL 改寫后的 SQL:
我們格式化一下 SQL:
可以看到 MySQL 將
select from A where A.x not in (select x from B) //非關(guān)聯(lián)子查詢
轉(zhuǎn)換成了
select from A where not exists (select 1 from B where B.x = a.x) //關(guān)聯(lián)子查詢
如果我們自己是 MySQL,在執(zhí)行非關(guān)聯(lián)子查詢時(shí),可以使用很簡單的策略:
select from A where A.x not in (select x from B where ...) //非關(guān)聯(lián)子查詢:1. 掃描 B 表中的所有記錄,找到滿足條件的記錄,存放在臨時(shí)表 C 中,建好索引2. 掃描 A 表中的記錄,與臨時(shí)表 C 中的記錄進(jìn)行比對,直接在索引里比對,
而關(guān)聯(lián)子查詢就需要循環(huán)迭代:
select from A where not exists (select 1 from B where B.x = a.x and ...) //關(guān)聯(lián)子查詢掃描 A 表的每一條記錄 rA: ? ? 掃描 B 表,找到其中的第一條滿足 rA 條件的記錄。
顯然,關(guān)聯(lián)子查詢的掃描成本會高于非關(guān)聯(lián)子查詢。
我們希望 MySQL 能先"緩存"子查詢的結(jié)果(緩存這一步叫物化,MATERIALIZATION),但MySQL 認(rèn)為不緩存更快,我們就需要給予 MySQL 一定指導(dǎo)。
...
可以看到執(zhí)行時(shí)間變成了 0.67s。
整理
我們診斷的關(guān)鍵點(diǎn)如下:
\1. 對于 information_schema 中的元數(shù)據(jù)表,執(zhí)行計(jì)劃不能提供有效信息。
\2. 通過查看 MySQL 改寫后的 SQL,我們猜測了優(yōu)化器發(fā)生了誤判。
\3. 我們增加了 hint,指導(dǎo) MySQL 正確進(jìn)行優(yōu)化判斷。
但目前我們的實(shí)驗(yàn)僅限于猜測,猜中了萬事大吉,猜不中就無法做出好的診斷。
1.首先我的表默認(rèn)是:innoDB,這種表的類型不支持全文檢索,所以要先改變其類型為MyISAM。
alter news_info title engine=MyISAM;
2.然后要在對應(yīng)的要進(jìn)行查找的字段上面建立全文檢索的索引:
alter news_info add fulltext index(title);
如果要同時(shí)對多個字段進(jìn)行檢索可以這樣:
問題
我們有一個 SQL,用于找到?jīng)]有主鍵 / 唯一鍵的表,但是在 MySQL 5.7 上運(yùn)行特別慢,怎么辦?
實(shí)驗(yàn)
我們搭建一個 MySQL 5.7 的環(huán)境,此處省略搭建步驟。
寫個簡單的腳本,制造一批帶主鍵和不帶主鍵的表:
執(zhí)行一下腳本:
現(xiàn)在執(zhí)行以下 SQL 看看效果:
...
執(zhí)行了 16.80s,感覺是非常慢了。
現(xiàn)在用一下 DBA 三板斧,看看執(zhí)行計(jì)劃:
感覺有點(diǎn)慘,由于 information_schema.columns 是元數(shù)據(jù)表,沒有必要的統(tǒng)計(jì)信息。
那我們來 show warnings 看看 MySQL 改寫后的 SQL:
我們格式化一下 SQL:
可以看到 MySQL 將
select from A where A.x not in (select x from B) //非關(guān)聯(lián)子查詢
轉(zhuǎn)換成了
select from A where not exists (select 1 from B where B.x = a.x) //關(guān)聯(lián)子查詢
如果我們自己是 MySQL,在執(zhí)行非關(guān)聯(lián)子查詢時(shí),可以使用很簡單的策略:
select from A where A.x not in (select x from B where ...) //非關(guān)聯(lián)子查詢:1. 掃描 B 表中的所有記錄,找到滿足條件的記錄,存放在臨時(shí)表 C 中,建好索引2. 掃描 A 表中的記錄,與臨時(shí)表 C 中的記錄進(jìn)行比對,直接在索引里比對,
而關(guān)聯(lián)子查詢就需要循環(huán)迭代:
select from A where not exists (select 1 from B where B.x = a.x and ...) //關(guān)聯(lián)子查詢掃描 A 表的每一條記錄 rA: ? ? 掃描 B 表,找到其中的第一條滿足 rA 條件的記錄。
顯然,關(guān)聯(lián)子查詢的掃描成本會高于非關(guān)聯(lián)子查詢。
我們希望 MySQL 能先"緩存"子查詢的結(jié)果(緩存這一步叫物化,MATERIALIZATION),但MySQL 認(rèn)為不緩存更快,我們就需要給予 MySQL 一定指導(dǎo)。
...
可以看到執(zhí)行時(shí)間變成了 0.67s。
整理
我們診斷的關(guān)鍵點(diǎn)如下:
\1. 對于 information_schema 中的元數(shù)據(jù)表,執(zhí)行計(jì)劃不能提供有效信息。
\2. 通過查看 MySQL 改寫后的 SQL,我們猜測了優(yōu)化器發(fā)生了誤判。
\3. 我們增加了 hint,指導(dǎo) MySQL 正確進(jìn)行優(yōu)化判斷。
但目前我們的實(shí)驗(yàn)僅限于猜測,猜中了萬事大吉,猜不中就無法做出好的診斷。
分享名稱:mysql怎么查詢速度,如何優(yōu)化mysql查詢速度
標(biāo)題路徑:http://aaarwkj.com/article44/hchjee.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、響應(yīng)式網(wǎng)站、網(wǎng)站收錄、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站營銷、ChatGPT
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)