久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

MySQL查詢語句很慢如何解決

190次閱讀
沒有評論

共計 2066 個字符,預(yù)計需要花費(fèi) 6 分鐘才能閱讀完成。

今天就跟大家聊聊有關(guān) MySQL 查詢語句很慢如何解決,可能很多人都不太了解,為了讓大家更加了解,丸趣 TV 小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

連接查詢的優(yōu)化

無論什么數(shù)據(jù)庫,多表連接的查詢成本都是比較高的,因此對于高并發(fā)應(yīng)用,應(yīng)該盡量減少有連接的查詢,多表連接的個數(shù)不要超過 4 張表。一般數(shù)據(jù)量少的時候,連接開小不大,一般不會有性能問題,當(dāng)數(shù)據(jù)量變大后,那么性能問題就會比較突出。所以在數(shù)據(jù)庫初期最好能確定哪個表能成為大表,然后進(jìn)行反范式設(shè)計減少連接的表,例如增加冗余字段等等,或者在業(yè)務(wù)代碼中進(jìn)行連接計算。

一些經(jīng)驗總結(jié)點:

1、ON、USING 字句中的列確認(rèn)有索引,如果連接的順序為 B、A,那么只需在 A 表的列上創(chuàng)建索引即可,無需在 B 中建索引,可以減少不必要索引開銷。

查詢舉例:

SELECT B.*,A.* FROM B JOIN A ON B.col1 = A.col2

MYSQL 會全表掃描 B 表,對 B 表的每一行記錄去尋找 A 表記錄,所以需用 A 表 COL2 列上索引來提高效率。

2、使用 EXPLAIN 檢查連接,看 ROWS 列,如果該列值太高,比如幾千,上萬的,那么就需要考慮是否索引無效后者連接表的順序不對了。

3、考慮在應(yīng)用層實現(xiàn)連接查詢,例如可以在 JAVA 中把復(fù)雜的查詢分解為幾個簡單查詢,得到一個較小的結(jié)果集合,處理遍歷后,再根據(jù)條件獲取完整數(shù)據(jù),這樣做往往更高效,因為把數(shù)據(jù)分離,更不容易變化,有利于數(shù)據(jù)庫緩存數(shù)據(jù)。

舉例如下:

SELECT a.* FROM A WHERE a.id IN(1,2,3,4,5,6,7,8,9,10);

如果 id=1~8 的記錄已經(jīng)被存儲在緩存 REDIS 中了,那么我們只需要查詢 id= 9 和 10 的數(shù)據(jù),這樣減少了很多數(shù)據(jù)庫連接交互,可以提高性能。

GROUP BY、DISTINCT、ORDER BY 語句優(yōu)化

這些語句默認(rèn)都要進(jìn)行 ORDER BY 排序,優(yōu)化的思路比較類似。

1、如果多張表進(jìn)行連接查詢,ORDER BY 的列應(yīng)屬于連接順序的第一張表。如果不在同一個表中,那么可以考慮冗余一些列,或者合并表。

2、需要保證索引列和 ORDER BY 的列相同,且各列按照相同的方向進(jìn)行排序。

3、指定 ORDER BY NULL,默認(rèn)情況下,MYSQL 將排序所有 GROUP BY 的查詢,如果想要避免排序結(jié)果所產(chǎn)生的消耗,可以指定 ORDER BY NULL。

舉例如下:

select count(1) from sys_dept group by dept_id order by null limit 3

子查詢優(yōu)化

由于子查詢可讀性比較符合開發(fā)人員的思路習(xí)慣,所以都習(xí)慣編寫子查詢,但子查詢在生產(chǎn)環(huán)境中,是最常見的性能瓶頸。

對于數(shù)據(jù)庫來說,大部分情況下,連接比子查詢更快,優(yōu)化器一般可以生成更佳的執(zhí)行計劃,可以余弦裝載數(shù)據(jù),更高效的處理查詢,子查詢生成的臨時表也沒有索引,因此效率會更低。

目前的實踐來說,子查詢應(yīng)該盡量改寫成 JOIN 的寫法

舉個常見的例子

SELECT c1 FROM t1 where t1.c1 IN (SELECT c1 FROM t2);

我們可以轉(zhuǎn)化為連接的方式:

SELECT c1 FROM t1.c1 FROM t1,t2 WHERE t1.c1=t2.c2

優(yōu)化 IN 列表

對于 IN 列表,MySQL 會排序里面的值,并使用二分查找方式去定位數(shù)據(jù),把 IN 字句改寫成 OR 形式其實沒什么用。IN 列表不建議太長,對于高并發(fā)業(yè)務(wù),建議不超過幾十個。優(yōu)化思路可以轉(zhuǎn)化為多個等于的查詢。例如下面的語句,如果 ID 值很多,其實性能不會太好。

SELECT * FROM A where A.ID IN(SELECT id FROM B)

優(yōu)化思路:

可以從程序業(yè)務(wù)層出發(fā),先查詢 SELECT id FROM B,然后獲取到 ID 的值,逐步和 SELECT * FROM A 進(jìn)行拼接,轉(zhuǎn)化為 SELECT * FROM A where ID =?的形式。

優(yōu)化 UNION

UNION 語句默認(rèn)是去除重復(fù)記錄,需要用到排序操作,如果結(jié)果集很大,成本會很高,建議盡量使用 UNION ALL 語句,對于 UNION 多個分表場景,應(yīng)盡可能在數(shù)據(jù)庫分表的時候,就確定各個分表數(shù)據(jù)唯一性,這樣就無需使用 UNION 來去重了。

另外查詢語句外的 WHERE 條件并不會應(yīng)用到每個單獨(dú)的 UNION 子句中,所以每個 UNION 子句都添加 where 條件。

優(yōu)化 BLOB、TEXT 類型字段的查詢

由于 mysql 內(nèi)存臨時表暫不支持 BLOB、TEXT 類型,如果包含他們的查詢就要用到基于磁盤的臨時表,性能會很低,所以如無必要,查詢條件就不要這 2 種類型。

優(yōu)化思路:

1、如果必須使用,可以考慮拆分表,把 BLOB、TEXT 字段分離到單獨(dú)的表中。

2、如果有許多大字段,可以考慮合并這些字段到一個字段,存儲一個大 200KB 比存儲 20 個 10KB 更有效。

3、考慮使用 COMPRESS(),再存儲。

看完上述內(nèi)容,你們對 MySQL 查詢語句很慢如何解決有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注丸趣 TV 行業(yè)資訊頻道,感謝大家的支持。

正文完
 
丸趣
版權(quán)聲明:本站原創(chuàng)文章,由 丸趣 2023-08-03發(fā)表,共計2066字。
轉(zhuǎn)載說明:除特殊說明外本站除技術(shù)相關(guān)以外文章皆由網(wǎng)絡(luò)搜集發(fā)布,轉(zhuǎn)載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 忻城县| 固原市| 杭锦旗| 大石桥市| 行唐县| 怀远县| 巴彦淖尔市| 龙州县| 宁安市| 石柱| 临邑县| 乌拉特中旗| 白朗县| 余江县| 玛曲县| 高雄市| 九台市| 平乐县| 米泉市| 高平市| 三明市| 西充县| 娄底市| 个旧市| 延安市| 华坪县| 玛沁县| 谢通门县| 抚远县| 宝坻区| 宁城县| 嘉义市| 师宗县| 惠来县| 钟山县| 灌云县| 屏东县| 丹棱县| 昌图县| 彩票| 柘城县|