當前位置:首頁 » 編程語言 » mysql查詢慢sql
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

mysql查詢慢sql

發布時間: 2023-05-24 11:35:02

1. Mysql查詢效率很慢的問題如何分析和解決

MySQL 在崩潰恢復時,會遍歷打開所有 ibd 文件的 header page 驗證數據字典的准確性,如果 MySQL 中包含了大量表,這個校驗過程就會比較耗時。 MySQL 下崩潰恢復確實和表數量有關,表總數越大,崩潰恢復時間越長。另外磁碟 IOPS 也會影響崩潰恢復時間,像這里開發庫的 HDD IOPS 較低,因此面對大量的表空間,校驗速度就非常緩慢信蘆枝。另外一個發現,MySQL 8 下正常啟用時居然也會進行表空間校驗,而故障恢復時則會額外再進行一次表空間校驗,等於校驗了 2 遍。不過 MySQL 8.0 里多了一個特性,即表數量超過 5W 時,會啟用多線程掃描,加快表空間校驗過程。
如何跳過校驗MySQL 5.7 下有方法可以跳過崩潰恢復時的表空間校驗過程嘛?查閱了資料,方法主要有兩種:
1. 配置 innodb_force_recovery可以使 srv_force_recovery != 0 ,那麼 validate = false,即可以跳過表空間校驗。實際測試的時候設置 innodb_force_recovery =1,也就是強制恢復跳過壞頁,就可以跳過校驗,然後重啟就是正常啟動了。通過這種臨時方式可以避免崩潰恢復後非常耗時的表空間校驗過程,快速啟動 MySQL,個人目前暫時未發現有什麼隱患。2. 使用共享表空間替代獨立表空間這樣就不需要打開 N 個 ibd 文件了,只需要打開一個 ibdata 文件即可,大大節省了校驗時間。自從聽了姜老師講過使用共享表空間替代獨立表空間解決 drop 大表時性能抖動的原理後,感覺共享表空間在很多業務環境下,反嘩碰而更有優勢。
臨時冒出另外一種解決想法,即用 GDB 調試崩潰恢復,通過臨時修改 validate 變數值讓 MySQL 跳過表空間驗證過程,然後讓 MySQL 正常關閉,重新啟動就可以正常啟動了。但是實際測試發現,如果以 debug 模式運行,確實可以臨時修改 validate 變數,跳過表空間驗證過程,但是 debug 模式下代碼運行效率大打折扣,反而耗時更長。而以非滑敏 debug 模式運行,則無法修改 validate 變數,想法破滅。

2. 如何優化MySQL中查詢慢的SQL語句啊

MySQL查詢優化的5個好用方法
http://soft.chinabyte.com/database/254/11335754.shtml

原則上來說

FIND_IN_SET
typeid IN (35)
arcrank
加復合索引
在sortrank加索引

3. 記錄一次慢sql排查

mysql的慢日誌中,看到有這么一條

不算太復雜的一條sql,但是掃了200多萬行的數據,所以慢。先看執行計劃

mysql> explain SELECT
-> lu.userId,
-> lu.userName,
-> lu.photo userImage,
-> lu.sex,
-> wc.typeId AS courseType,
-> wc.name AS courseName,
-> lc.className,
-> DATE_FORMAT(wcu.CreatedTime, '%Y-%m-%d %H:%i:%s') AS time
-> FROM
-> wkt_courseclassuser wcu
-> INNER JOIN wkt_course wc on wcu.courseId = wc.id
-> INNER JOIN lxx_user lu ON wcu.userId = lu.userId
-> INNER JOIN (select t.* from (select * from lxx_classuserrecord WHERE classtypeid =1 ORDER BY CreateTime desc) t GROUP BY t.userid ) lcur ON lcur.userid = lu.userId
-> INNER JOIN lxx_class lc on lc.classId = lcur.classId
-> INNER JOIN lxx_registerschool lr ON lr.schoolKey = lu.schoolKey
-> WHERE lc.status = 1 and lc.typeId = 1
-> and lr.schoolId = 60800000000000001
-> and wc.typeId in (1,2,3,23)
-> ORDER BY wc.CreateTime DESC
-> LIMIT 100;
+----+-------------+---------------------+--------+----------------------------------------------------------------------------------------------------------------+----------------------------------+---------+-------------------------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------------+--------+----------------------------------------------------------------------------------------------------------------+----------------------------------+---------+-------------------------+-------+----------------------------------------------+
| 1 | PRIMARY | lr | ref | lxx_registerSchool_schoolId | lxx_registerSchool_schoolId | 9 | const | 1 | Using where; Using temporary; Using filesort |
| 1 | PRIMARY | lu | ref | PRIMARY,index_lxx_user_schoolKey | index_lxx_user_schoolKey | 603 | wkt_school.lr.schoolKey | 79 | Using where |
| 1 | PRIMARY | <derived2> | ref | <auto_key1> | <auto_key1> | 8 | wkt_school.lu.userId | 15 | Using where |
| 1 | PRIMARY | lc | eq_ref | PRIMARY | PRIMARY | 8 | lcur.classid | 1 | Using where |
| 1 | PRIMARY | wcu | ref | index_wkt_courseclassuser_courseId,index_wkt_courseclassuser_userId,index_wkt_courseclassuser_courseId_classId | index_wkt_courseclassuser_userId | 9 | wkt_school.lu.userId | 47 | Using where |
| 1 | PRIMARY | wc | eq_ref | PRIMARY | PRIMARY | 8 | wkt_school.wcu.courseId | 1 | Using where |
| 2 | DERIVED | <derived3> | ALL | NULL | NULL | NULL | NULL | 47204 | Using temporary; Using filesort |
| 3 | DERIVED | lxx_classuserrecord | ALL | NULL | NULL | NULL | NULL | 47204 | Using where; Using filesort |
+----+-------------+---------------------+--------+----------------------------------------------------------------------------------------------------------------+----------------------------------+---------+-------------------------+-------+----------------------------------------------+

乍一看好像最大的rows才47204,為什麼實際執行掃描行數要大這么多呢?

網上找到一篇解釋
https://dba.stackexchange.com/questions/73520/mysql-explain-has-different-row-count-than-slow-query-log

大概意思是,explain只是根據數據的特徵,大概估算要掃描的行數,實際執行時,特別是需要做join操作時,結果集都是n*m的,因此實際執行結果可能要大很多。

看到執行計劃最後兩行,都是需要Using filesort的。很明顯是產生於

INNER JOIN (select t.* from (select * from lxx_classuserrecord WHERE classtypeid =1 ORDER BY CreateTime desc) t GROUP BY t.userid ) lcur ON lcur.userid = lu.userId

一行。因為INNER JOIN的是一個子查詢的結果, 上面不會有索引 ,而且這個子查詢的結果集也有幾萬條,開始的直觀感覺是慢在這里。結果優化了很久,也沒什麼效果。最後把這個關聯條件也去掉了,發現查詢時間還是跟原來差不多,因此問題不是在此。

PS:第一次沒有看懂explain的結果。explain中的第三行從derived2的結果中,也就是id為2的那條派生表查詢中,自動建立了一個auto_key1的索引,因此inner join上面那行子查詢並不會很慢

東找西找,發現去掉ORDER BY wc.CreateTime DESC以後,就變得很快了。查看了一下wkt_course的索引,果然CreateTime沒有索引。趕緊補一下
CREATE INDEX index_wkt_course_CreateTime ON wkt_course(CreateTime)

然後再explain一下,

| 1 | PRIMARY | lr | ref | lxx_registerSchool_schoolId | lxx_registerSchool_schoolId | 9 | const | 1 | Using where; Using temporary; Using filesort |

第一行這里沒有任何改觀。實際執行起來也絲毫沒有變快。

再靜下來,仔細分析一下問題在哪裡。mysql估計是先執行了連表查詢,然後對這個結果集創建臨時表,然後進行排序,最後在取出前100。用select count(*) 在去掉limit限制後數了一下,這個結果集有80多萬條數據,怪不得排序很慢。這里總結出來一個經驗,就是看explain首先要關注Using temporary,其次是Using filesort的問題。

要使ORDER BY的欄位走索引,則需要讓欄位所在的表成為驅動表
https://blog.csdn.net/zerou8400/article/details/95389044

最終的解決方案,在order by的欄位建立索引,並且使用straight_join,強制指定wkt_course為驅動表
SELECT
lu.userId,
lu.userName,
lu.photo userImage,
lu.sex,
wc.typeId AS courseType,
wc.name AS courseName,
lc.className,
DATE_FORMAT(wcu.CreatedTime, '%Y-%m-%d %H:%i:%s') AS time
FROM
wkt_course wc
straight_join wkt_courseclassuser wcu ON wcu.courseId = wc.id
INNER JOIN lxx_user lu ON wcu.userId = lu.userId
INNER JOIN lxx_registerschool lr on lr.schoolKey = lu.schoolKey
INNER JOIN (select t.* from (select * from lxx_classuserrecord WHERE classtypeid =1 ORDER BY CreateTime desc) t GROUP BY t.userid ) lcur ON lcur.userid = lu.userId
INNER JOIN lxx_class lc on lc.classId = lcur.classId
WHERE lr.schoolId = 60800000000000001
and wc.typeId in (1,2,3,23)
and lc.status = 1 and lc.typeId = 1
ORDER BY wc.CreateTime DESC
LIMIT 100;

圍觀一下優化後的執行計劃
mysql> explain SELECT
-> lu.userId,
-> lu.userName,
-> lu.photo userImage,
-> lu.sex,
-> wc.typeId AS courseType,
-> wc.name AS courseName,
-> lc.className,
-> DATE_FORMAT(wcu.CreatedTime, '%Y-%m-%d %H:%i:%s') AS time
-> FROM
-> wkt_course wc
-> straight_join wkt_courseclassuser wcu ON wcu.courseId = wc.id
-> INNER JOIN lxx_user lu ON wcu.userId = lu.userId
-> INNER JOIN lxx_registerschool lr on lr.schoolKey = lu.schoolKey
-> INNER JOIN (select t.* from (select * from lxx_classuserrecord WHERE classtypeid =1 ORDER BY CreateTime desc) t GROUP BY t.userid ) lcur ON lcur.userid = lu.userId
-> INNER JOIN lxx_class lc on lc.classId = lcur.classId
-> WHERE lr.schoolId = 60800000000000001
-> and wc.typeId in (1,2,3,23)
-> and lc.status = 1 and lc.typeId = 1
-> ORDER BY wc.CreateTime DESC
-> LIMIT 100;
+----+-------------+---------------------+--------+----------------------------------------------------------------------------------------------------------------+------------------------------------+---------+-----------------------+-------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------------+--------+----------------------------------------------------------------------------------------------------------------+------------------------------------+---------+-----------------------+-------+---------------------------------+
| 1 | PRIMARY | wc | index | PRIMARY | index_wkt_course_CreateTime | 6 | NULL | 1 | Using where |
| 1 | PRIMARY | lr | ref | lxx_registerSchool_schoolId | lxx_registerSchool_schoolId | 9 | const | 1 | NULL |
| 1 | PRIMARY | wcu | ref | index_wkt_courseclassuser_courseId,index_wkt_courseclassuser_userId,index_wkt_courseclassuser_courseId_classId | index_wkt_courseclassuser_courseId | 9 | wkt_school.wc.id | 31 | Using where |
| 1 | PRIMARY | lu | eq_ref | PRIMARY,index_lxx_user_schoolKey | PRIMARY | 8 | wkt_school.wcu.userId | 1 | Using where |
| 1 | PRIMARY | <derived2> | ref | <auto_key1> | <auto_key1> | 8 | wkt_school.wcu.userId | 15 | Using where |
| 1 | PRIMARY | lc | eq_ref | PRIMARY | PRIMARY | 8 | lcur.classid | 1 | Using where |
| 2 | DERIVED | <derived3> | ALL | NULL | NULL | NULL | NULL | 36487 | Using temporary; Using filesort |
| 3 | DERIVED | lxx_classuserrecord | ALL | NULL | NULL | NULL | NULL | 36487 | Using where; Using filesort |
+----+-------------+---------------------+--------+----------------------------------------------------------------------------------------------------------------+------------------------------------+---------+-----------------------+-------+---------------------------------+

https://blog.csdn.net/m0_37894254/article/details/80675733

4. 如何在mysql查找效率慢的SQL語句

  • 查看慢SQL是否啟用,查看命令:show variables like 'log_slow_queries';

    如果結果為ON則是開啟了,如果為OFF則表示禁用了。

  • 開啟慢查詢命令:set global log_slow_queries = on;

  • 查看是否開啟:show variables like 'log_slow_queries';

  • 查看慢查詢參數,即設置超過多少秒的查詢歸為了慢查詢。參數為:long_query_time,查詢命令:showglobal variables like 'long_query_time';

    mysql默認時間為10秒,即10秒及以上的查詢被歸為了慢查詢。我們的實際項目中根本就不可能這么包容你,所以得提供查詢效率優化sql,讓程序更快的執行。

  • 這里設置時間為1秒,即超過1秒就會被認為慢查詢。設置命令:set global long_query_time =1;用命令設置的,會立即生效,不用重啟mysql服務。但重啟mysql服務後就會失效。

  • 查看設置的時間,show global variables like 'long_query_time';即可看到現在已經變為1秒了

  • 查看慢查詢存放日誌,命令:show variables like 'slow_query_log_file';

    去相應目錄下查看即可。

5. MySQL刪除千萬級數據量導致的慢查詢優化

有人刪了千萬級的數據,結果導致頻繁的慢查詢。

線上收到大量慢查詢告警,於是檢查慢查詢的SQL,發現不是啥復雜SQL,這些SQL主要針對一個表,基本都是單行查詢,看起來應該不會有慢查詢。這種SQL基本上都是直接根據索引查找出來的,性能應該極高。

是否可能慢查詢不是SQL問題,而是MySQL生產伺服器的問題?特殊情況下,MySQL出現慢查詢還真不是SQL問題,而是他自己生產伺服器的負載太高,導致SQL語句執行慢。比如現在MySQL伺服器的

磁碟I/O負載高,每秒執行大量高負載的隨機I/O,但磁碟本身每秒能執行的隨機I/O有限,導致輪吵櫻正常SQL在磁碟執行時,若跑一些隨機IO,臘叢你的磁碟太忙,顧不上你了,導致你本來很快的一個SQL,要等很久才能執行完畢,這時就可能導致正常SQL也變成慢查詢。

也許網路負載高,導致你一個SQL語句要發到MySQL,光是等待獲取一個和MySQL的連接,都很難,要等很久或MySQL自己網路負載太高,碰知帶寬打滿,帶寬打滿後,你一個SQL也許執行很快,但其查出來的數據返回給你,網路都送不出去,也會變成慢查詢。

若CPU負載過高,也會導致CPU過於繁忙去執行別的任務,沒時間執行你的SQL。

所以慢查詢不一定是SQL本身導致,若覺得SQL不應該會慢查詢,結果他那個時間段跑這個SQL 就是慢,應排查當時MySQL伺服器的負載,尤其看看磁碟、網路及 CPU 的負載,是否正常。

當某個離線作業瞬間大批量把數據往MySQL里灌入的時,他一瞬間伺服器磁碟、網路以及CPU的負載會超高。

此時你一個正常SQL執行下去,短時間內一定會慢查詢,類似問題,優化手段更多是控制你導致MySQL負載過高的那些行為,比如灌入大量數據,最好在業務低峰期灌入,別影響高峰期的線上系統運行。

但看了下MySQL伺服器的磁碟、網路以及CPU負載,一切正常,似乎也不是這問題導致。看起來無解了?

慢 SQL 的頭兩步排查手段:

這兩種辦法都不奏效之後,第三步:用MySQL profilling工具去細致的分析SQL語句的執行過程和耗時。

這個工具可以對SQL語句的執行耗時進行非常深入和細致的分析

打開profiling,使用

接著MySQL就會自動記錄查詢語句的profiling信息。此時若執行show profiles,就會給你列出各種查詢語句的profiling信息,會記錄下來每個查詢語句的query id,所以你要針對你需要分析的query找到對他的query id,我們當時就是針對慢查詢的那個SQL語句找到了query id。

然後針對單個查詢語句,看其profiling信息,使用show profile cpu, block io for query xx,這里的xx是數字,此時就可以看到具體的profile信息。

除了cpu以及block io以外,還能指定去看這個SQL語句執行時候的其他各項負載和耗時。

會給你展示出來SQL語句執行時候的各種耗時,比如磁碟IO的耗時,CPU等待耗時,發送數據耗時,拷貝數據到臨時表的耗時等,SQL執行過程中的各種耗時都會展示。

檢查該SQL語句的profiling信息後,發現問題,其Sending Data耗時最高,幾乎使用1s,占據SQL執行耗時的99%!其他環節耗時低可以理解,畢竟這種簡單SQL執行速度真的很快,基本就是10ms級別,結果跑成1s,那肯定Sending Data就是問題根源!

這Sending Data在幹啥呢?

MySQL官方釋義:為一個SELECT語句讀取和處理數據行,同時發送數據給客戶端的過程,簡單來說就是為你的SELECT語句把數據讀出來,同時發送給客戶端。

但這過程為啥這么慢?profiling確實是提供給我們更多的線索了,但似乎還是沒法解決問題。但已經捕獲到異常關鍵點,就是Sending Data的耗時很高!

接著:

看innodb存儲引擎的一些狀態,此時發現一個奇怪的指標:history list length,值特別高,達到上萬。

MVCC就是多個事務在對同一個數據, 有人寫,有人讀,此時可以有多種隔離級別,對一個數據有個多版本快照鏈條,才能實現MVCC和各種隔離級別。

所以當你有大量事務執行時,就會構建這種undo多版本快照鏈條,此時history list length就會很高。然後在事務提交後,會有一個多版本快照鏈條的自動purge清理機制,清理了,該值就會降低。一般該值不應過高,所以注意到第二個線索:history list length過高,即大量的undo多版本鏈條數據沒有清理。推測可能有的事務長時間運行,所以其多版本快照不能被purge清理,進而導致history list length過高。

經過這倆線索推測,在大量簡單SQL變成慢查詢時,SQL因為Sending Data環節異常,耗時過高;同時此時出現一些長事務長時間運行,大量的頻繁更新數據,導致有大量undo多版本快照鏈條,還無法purge清理。

因為發現有大量的更新語句在活躍,而且有那種長期活躍的長事務一直在跑而沒有結束,問了下系統負責人,在後台跑了個定時任務:他居然開了一個事務,然後在一個事務里刪除上千萬數據,導致該事務一直在運行。

這種長事務的運行會導致你刪除時,僅只是對數據加了一個刪除標記,事實上並沒有徹底刪除。此時你若和長事務同時運行的其它事務里再查詢,他在查詢時可能會把那上千萬被標記為刪除的數據都掃描一遍。因為每次掃描到一批數據,都發現標記為刪除了,接著就會再繼續往下掃描,所以才導致一些查詢語句很慢。

那為何你啟動一個事務,在事務里查詢,憑什麼就要去掃描之前那個長事務標記為刪除狀態的上千萬的垃圾數據?講道理,那些數據都被刪了,跟你沒關系了呀,你可以不去掃描他們 嘛!

而問題症結在於,那個 刪除千萬級數據的事務是個長事務 !即當你啟動新事務查詢時,那個刪除千萬級數據的長事務一直在運行,它是活躍的!結合MVCC的Read View機制,當你啟動一個新事務查詢時,會生成一個Read View。你的新事務查詢時,會根據ReadView去判斷哪些數據可見及可見的數據版本號,因為每個數據都有個版本鏈條,有時你能可見的僅是這個數據的一個 歷史 版本。

所以正是因為該長事務一直在運行,還在刪除大量數據,而且這些數據僅是邏輯刪除,所以此時你新開事務的查詢還是會讀到所有邏輯刪除數據,也就會出現千萬級的數據掃描,導致了慢查詢!

所以禁止在業務高峰期運行那種刪除大量數據的語句,因為這可能導致一些正常的SQL都變慢查詢,因為那些SQL也許會不斷掃描你標記為刪除的大量數據,好不容易掃描到一批數據,結果發現是標記為刪除的,於是繼續掃描下去,導致慢查詢!

直接kill那個正在刪除千萬級數據的長事務,所有SQL很快恢復正常。此後,大量數據清理全部放在凌晨執行,那個時候就沒什麼人使用系統了,所以查詢也很少。

6. 如果mysql裡面的數據過多,查詢太慢怎麼辦

問題

我們有一個 SQL,用於找到沒有主鍵 / 唯一鍵的表,但是在 MySQL 5.7 上運行特別慢,怎麼辦?


實驗

我們搭建一個 MySQL 5.7 的環境,此處省略搭建步驟。

寫個簡單的腳本,製造一批帶主鍵和不帶主鍵的表:

可以看到執行時間變成了 0.67s。

整理

我們診斷的關鍵點如下:

1. 對於 information_schema 中的元數據表,執行計劃不能提供有效信息。

2. 通過查看 MySQL 改寫後的 SQL,我們猜測了優化器發生了誤判。

3. 我們增加了 hint,指導 MySQL 正確進行優化判斷。

但目前我們的實驗僅限於猜測,猜中了萬事大吉,猜不中就無法做出好的診斷。

7. 如何查找MySQL中查詢慢的SQL語句

1、首先,要開啟mysql的慢查詢日誌。在mysql的配置文件:my.ini中添加如下兩個配置項:
log-slow-queries = E:\Servers\MySql5.5\data\mysql_slow_query.log //mysql慢查詢日誌記錄位置
long_query_time=5 //定義慢查詢sql的時間,當前配置表示超過5秒的sql為慢查詢,進入到日誌里
2、查詢慢查詢日誌
找到配置的慢查詢日誌文件,如E:\Servers\MySql5.5\data\mysql_slow_query.log ,這里就是所有的慢查詢sql啦

8. mysql 慢查詢 會影響其他查詢嗎

肯定影響的。

常見查詢慢的原因常見的話會有如下幾種:
1、沒有索引或沒有用到索引。
PS:索引用來快速地尋找那些具有特定值的記錄,所有MySQL索引都以B-樹的形式保存。如果沒有索引,執行查詢時MySQL必須從第一個記錄開始掃描整個表 的所有記錄,直至找到符合要求的記錄。表裡面的記錄數量越多,這個操作的代價就越高。如果作為搜索條件的列上已經創建了索引,MySQL無需掃描任何記錄 即可迅速得到目標記錄所在的位置。如果表有1000個記錄,通過索引查找記錄至少要比順序掃描記錄快100倍。
索引類型:
普通索引:這是最基本的索引類型,沒唯一性之類的限制。
唯一性索引:和普通索引基本相同,但所有的索引列只能出現一次,保持唯一性。
主鍵:主鍵是一種唯一索引,但必須指定為"PRIMARY KEY"。
全文索引:MYSQL從3.23.23開始支持全文索引和全文檢索。在MYSQL中,全文索引的索引類型為FULLTEXT。全文索引可以在VARCHAR或者TEXT類型的列上創建。
2、IO吞吐量小形成了瓶頸。
PS:這是從系統層來分析MYSQL是比較耗IO的。一般資料庫監控也是答穗比較關注IO。
監控命令:$iostat -d -k 1 10
參數 -d 表示,顯示設備(磁碟)使用狀態;-k某些使用block為單位的列強制使用Kilobytes為單位;1 10表示,數據顯示每隔1秒刷新一次,共顯示10次。
3、內存不足
監控內存使用:vmstat [-n] [延時[次數]]
Memory
swpd: 切換到交換內存上的內存(默認以KB為單位)
• 如果 swpd 的值不為0,或者還比較大,比如超過100M了,但是si, so 的值長期為0,這種情況我們可以不用擔心,不會影響系統性能。
free: 空閑的物理內存
buff: 作為buffer cache的內存,對塊設備的讀寫進行緩沖
cache: 作為page cache的內銷型存, 文件系統的cache• 如果 cache 的值大的時候,說明cache住的文件數多,如果頻繁訪問到的文件都能被cache住,那麼磁碟的讀IO bi 會非常小。
4、網路虧舉猜速度慢
ping IP -t 查看是否有丟包。
5、一次查詢的數據量過大。
比如沒有分頁查詢,一次提取上萬條記錄。資料庫有可能卡死。
6、出現死鎖
所謂死鎖: 是指兩個或兩個以上的進程在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去.
Show innodb status檢查引擎狀態 ,可以看到哪些語句產生死鎖。
執行show processlist找到死鎖線程號.然後KillprocessNo
7、返回了不必要的行或列
一般查詢SQL語句一定要將欄位明確指定。而不要使用*進行查詢
8、注意UNion和UNion all 的區別。UNION all好
UNION在進行表鏈接後會篩選掉重復的記錄,所以在表鏈接後會對所產生的結果集進行排序運算,刪除重復的記錄再返回結果。所以union all的效率肯定要高!

9. MySQL怎麼查詢比較耗時的sql語句

開啟慢查詢日誌即可
文件方式配置
MySQL
慢查詢的方法:

mysql
配置文件
my.cnf
中增加:
log-slow-queries=/opt/data/slowquery.log
long_query_time=2
log-queries-not-using-indexes
命令方式配置
MySQL
慢查詢的方法:
set
global
slow_query_log=on;
set
global
long_query_time=1;
set
global
slow_query_log_file=『/opt/data/slow_query.log』;
查詢
MySQL
慢查詢狀態的方法:
SHOW
VARIABLES
LIKE
'%query%';
解析
MySQL
慢查詢日誌的方法:
按照
sql
執行時間最長的前
20

sql:
mysqlmpslow
-s
t
-t
20
-g
'select'
/opt/data/slowquery.log

10. 如何查找MySQL中查詢慢的SQL語句

問題

我們有一個 SQL,用於找到沒有主鍵 / 唯一鍵的表,但是在 MySQL 5.7 上運行特別慢,怎麼辦?

實驗

我們搭建一個 MySQL 5.7 的環境,此處省略搭建步驟。

寫個簡單的腳本,製造一批帶主鍵和不帶主鍵的表:

可以看到執行時間變成了 0.67s。

整理

我們診斷的關鍵點如下:

1. 對於 information_schema 中的元數據表,執行計劃不能提供有效信息。

2. 通過查看 MySQL 改寫後的 SQL,我們猜測了優化器發生了誤判。

3. 我們增加了 hint,指導 MySQL 正確進行優化判斷。

但目前我們的實驗僅限於猜測,猜中了萬事大吉,猜不中就無法做出好的診斷。