這篇文章主要介紹了導(dǎo)致sql執(zhí)行速度慢的情況有哪些的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇導(dǎo)致sql執(zhí)行速度慢的情況有哪些文章都會(huì)有所收獲,下面我們一起來看看吧。
成都創(chuàng)新互聯(lián)為企業(yè)級(jí)客戶提高一站式互聯(lián)網(wǎng)+設(shè)計(jì)服務(wù),主要包括網(wǎng)站設(shè)計(jì)制作、成都做網(wǎng)站、成都app軟件開發(fā)、微信小程序、宣傳片制作、LOGO設(shè)計(jì)等,幫助客戶快速提升營銷能力和企業(yè)形象,創(chuàng)新互聯(lián)各部門都有經(jīng)驗(yàn)豐富的經(jīng)驗(yàn),可以確保每一個(gè)作品的質(zhì)量和創(chuàng)作周期,同時(shí)每年都有很多新員工加入,為我們帶來大量新的創(chuàng)意。
如果數(shù)據(jù)庫本身的性能壓力就比較大,資源比較緊張,CPU占用率或者IO利用率很高,這時(shí)會(huì)導(dǎo)致所有的語句執(zhí)行起來都比較慢。這種情況下首先要做的應(yīng)該是提升服務(wù)器的配置,然后觀察服務(wù)器的性能指標(biāo)是否平穩(wěn)。
如果遇到一個(gè)簡單的查詢長時(shí)間未返回結(jié)果,那么大概率是表被鎖住了。一般遇到這種情況,都是通過show processlist命令,查看sql語句的狀態(tài)。
如圖所示,id為8的語句正在等待一個(gè)MDL鎖,我們可以使用kill命令殺掉這個(gè)阻塞線程。
另外還可以通過表sys.schema_table_lock_waits查詢阻塞的線程id。
MySQL> select * from temp where id =3 for update;
當(dāng)我們訪問id=3這條記錄時(shí),使用了for update,表示要對這條語句加鎖。但是如果此時(shí)已經(jīng)有另一個(gè)事務(wù)對這條記錄加了鎖,并且一直持有不釋放鎖,那么當(dāng)前語句就會(huì)一直阻塞。
通過上圖可以看出,第一個(gè)語句不提交事務(wù),第二個(gè)語句就一直處于等待阻塞狀態(tài)。
我們執(zhí)行show processlist,
可以看出確實(shí)有一個(gè)線程處于阻塞狀態(tài)。
鎖沖突會(huì)導(dǎo)致執(zhí)行效率降低,進(jìn)而影響到業(yè)務(wù),需要我們重點(diǎn)關(guān)注。
mysql> select * from t where c=50000 limit 1;
如果字段c上面沒有索引,那么就只能走主鍵id順序掃描,一直掃描到第50000行才能停下來。
給表數(shù)據(jù)加索引可以快速提升查詢性能,一般來說,因?yàn)樗饕?dǎo)致的慢sql可能是我們平常開發(fā)過程中經(jīng)常遇到的。
有了索引,并不代表萬事大吉。如果一個(gè)比較復(fù)雜的sql,需要關(guān)聯(lián)很多表進(jìn)行查詢,即使每張表的索引都可以起到作用,但是由于數(shù)據(jù)量過多,即使都命中索引,掃描的行數(shù)仍然是巨大的。這樣sql的執(zhí)行速度仍然會(huì)受到很大影響。
一般來說,超過3個(gè)表的join就應(yīng)該盡量避免,將其拆分為多個(gè)查詢,使用空間換時(shí)間也不失為一個(gè)好辦法。
1. 無索引、索引失效導(dǎo)致
慢查詢?nèi)绻谝粡垘浊f數(shù)據(jù)的表中以一個(gè)沒有索引的列作為查詢條件,大部分情況下查詢會(huì)非常耗時(shí),這種查詢毫無疑問是一個(gè)慢 SQL 查詢。
所以對于大數(shù)據(jù)量的查詢,需要建立適合的索引來優(yōu)化查詢。雖然我們很多時(shí)候建立了索引,但在一些特定的場景下,索引還有可能會(huì)失效,所以索引失效也是導(dǎo)致慢查詢的主要原因之一。
2. 鎖等待
常用的存儲(chǔ)引擎有 InnoDB 和 MyISAM,前者支持行鎖和表鎖,后者只支持表鎖。
如果數(shù)據(jù)庫操作是基于表鎖實(shí)現(xiàn)的,試想下,如果一張數(shù)據(jù)表在更新時(shí),需要鎖住整張表,那么其它大量數(shù)據(jù)庫操作(包括查詢)都將處于等待狀態(tài),這將嚴(yán)重影響到系統(tǒng)的并發(fā)性能。這時(shí),InnoDB 存儲(chǔ)引擎支持的行鎖更適合高并發(fā)場景。
行鎖升級(jí)為表鎖的可能:
在批量更新操作時(shí),行鎖就很可能會(huì)升級(jí)為表鎖。
MySQL 認(rèn)為如果對一張表使用大量行鎖,會(huì)導(dǎo)致事務(wù)執(zhí)行效率下降,從而可能造成其它事務(wù)長時(shí)間鎖等待和更多的鎖沖突問題發(fā)生,致使性能嚴(yán)重下降,所以 MySQL 會(huì)將行鎖升級(jí)為表鎖。還有,行鎖是基于索引加的鎖,如果我們在更新操作時(shí),條件索引失效,那么行鎖也會(huì)升級(jí)為表鎖。
因此,基于表鎖的數(shù)據(jù)庫操作,會(huì)導(dǎo)致 SQL 阻塞等待,影響執(zhí)行速度。
行鎖相對表鎖來說,雖然粒度更細(xì),并發(fā)能力提升了,但也帶來了死鎖的問題。因此,在使用行鎖時(shí),我們要注意避免死鎖。
3. 不恰當(dāng)?shù)?SQL 語句
使用不恰當(dāng)?shù)?SQL 語句也是慢 SQL 最常見的誘因之一 :
在大數(shù)據(jù)表中使用 分頁查詢,以及對非索引字段進(jìn)行排序等等。
關(guān)于“導(dǎo)致sql執(zhí)行速度慢的情況有哪些”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“導(dǎo)致sql執(zhí)行速度慢的情況有哪些”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。