MySQL常見問題之SQL查詢慢

2021-10-16 22:32:06 字數 1401 閱讀 2072

可能是經常處理業務,最近總是聽到開發的同學說sql的查詢慢。然後問我為什麼,讓我在資料庫層面找原因。這樣的需求接的多了,對於這類需求,我已經有了一套比較官方的回答思路,我來說,大家看,看看還有什麼沒有考慮到的地方,歡迎指正。

首先,當有業務方對我說sql查詢慢的時候,一般我會先問幾個問題:

1、這個sql是偶爾比較慢還是一直這麼慢?

如果是偶爾比較慢,那大概率說明不是sql層面的問題,應該是在某個時間點遇到了資料庫的其他動作,導致產生了影響,例如:

第一、該條語句要掃瞄的表被加鎖了,所以導致拿不到資料,查詢很慢。

第二、查詢的時間點,恰好資料庫在重新整理髒頁,我們知道資料庫進行了更新操作之後,不會立刻將這些資料進行落盤,而是重新整理到redo log中去,等到空閒的時候,通過redo log裡面的日誌將資料同步到磁碟中去。

第三、當前時間點正在進行乙個大的備份任務,導致磁碟的io突然增高,記憶體和磁碟的互動速度變慢,自然而然,查詢的速度也就降下來了。

第四、其他未知的神秘力量,例如大表操作、大事務、網路頻寬被占用等等

如果是一直這麼慢,一般情況下,sql層面的問題可能比較大,而sql層面,首先要考慮這幾個要素:

1、表的資料量有多大?上億條還是只有幾萬條?如果是上億條,那還說得過去,如果是幾萬條但是速度很慢,大概率是sql質量太差。

2、是否向資料庫請求了不必要的資料,例如只需要100條資料,但是卻掃瞄了全表。也就是掃瞄行數和返回的行數相差太多,這個時候需要重新寫sql,避免不必要的資料訪問。

3、表中的字段是否擁有索引?sql是否使用到了索引?這種情況下,我們可以使用explain的方法檢視該sql的執行計畫,然後檢視執行計畫中的rows列和type列,其中rows列反映的是掃瞄的行數,而type列反映的是掃瞄該錶的方法。如果表沒有建立索引,應該根據sql的具體內容,為表建立相關的索引。

4、sql中是否使用了很多的關聯查詢和子查詢,例如sql中包含很多個left join或者對於乙個大的結果集進行group by操作。

5、如果表使用到了索引,就要看看索引建立的合理性了,是否在一些基數比較小的字段上建立了索引,導致索引的作用沒有發揮出來,還導致"回表"操作,引發效能損耗,此時,修改表的索引就變得很必要了。

6、比較隱蔽的乙個問題,就是欄位上如果進行了資料的型別轉換或者函式操作,那麼這個sql是用不到該字段的索引的,這個問題很早之前遇到過幾次,當時也是遲遲查不出來原因,例如

select *** from tbl where a*2 < 4

和select *** from tbl where a<2

是不一樣的,如果在a列上指定了索引,那麼前者不會用到索引,而後者才能用到索引。

分析完這些,如果效能還是比較差,那就應該針對sql進行優化了,通過explain檢視當前的查詢型別,針對sql進行重寫。如果重新之後還是不行,那可能就得從業務層面進行調整了,不過一般不用走到這一步,sql的問題都能夠解決。

Sql 常見問題

select from orders left join orderlines on orderlines.orderid orders.id where orders.id 12345select from orders left join orderlines on orderlines.ord...

Mysql常見問題

1.安裝,推薦使用非安裝版.把解壓後的檔案拷貝到c盤根目錄下,並把總目錄改為mysql.然後進入windows命令 控制台,在c mysql bin下面執行mysqld nt install把它安裝為乙個服務,然後呼叫net start mysql啟動它,停止的命令是net stop mysql 想...

mysql常見問題

按照表中某一欄位排序,若該字段可能存在空值,公升序排列時空值排在最前面,降序排列是空值排在最後面。公升序排列時如果想讓空值排在最後面,可以 order by field1 is null,field1 asc 這麼寫。例如有個user表,按照 seq欄位排序。select from user ord...