搜尋
首頁後端開發php教程my summer holiday英文作文 mysql 效能的檢查與最佳化方法

1.索引沒有建好;
2、sql寫法過於複雜;
3、設定錯誤;
4、機器實在負荷不了;
1、索引沒有建好
如果看到mysql消耗的cpu很大,可以用mysql的client工具來檢查。
在linux下執行
/usr/local/mysql/bin/mysql -hlocalhost -uroot -p
輸入密碼,如果沒有密碼,則不用-p參數就可以進到客戶端介面。
看看目前的運作情況
show full processlist
可以多執行幾次
這個指令可以看到目前正在執行的sql語句,它會告知執行的sql、資料庫名稱、執行的狀態、來自的客戶端ip、所使用的帳號、運行時間等資訊
在我的cache後端,這裡面大部分時間是看不到顯示任何sql語句的,我認為這樣才算比較正常。如果看到有很多sql語句,那麼這台mysql就一定會有效能問題
如果出現了效能問題,則可以進行分析:
1、是不是有sql語句卡住了?
這是出現比較多的情況,如果資料庫是採用myisam,那麼有可能有一個寫入的執行緒會把資料表給鎖定了,如果這條語句不結束,則其它語句也無法運作。
查看processlist裡的time這一項,看看有沒有執行時間很長的語句,要留意這些語句。
2、大量相同的sql語句正在執行
如果出現這種情況,則有可能是該sql語句執行的效率低下,同樣要留意這些語句。
然後把你所懷疑的語句統統集合一下,用desc(explain)來檢查這些語句。
首先看看一個正常的desc輸出:
mysql> desc select * from imgs where imgid=1651768337;
+----+-------------+ -------+-------+---------------+---------+-------- -+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+------------ ---+---------+---------+-------+------+-------+
| 1 | SIMPLE | imgs | const | PRIMARY | PRIMARY | 8 | const | 1 | |
+----+-------------+------- +-------+---------------+---------+---------+----- --+------+-------+
1 row in set (0.00 sec)
注意key、rows和Extra這三項,這語句回傳的結果說明了此sql會使用PRIMARY主鍵索引來查詢,結果集數量為1條,Extra沒有顯示,證明沒有用到排序或其他運算。由此結果可以推斷,mysql會從索引中查詢imgid=1651768337這條記錄,然後再到真實表中取出所有字段,是很簡單的操作。
key是指明當前sql會使用的索引,mysql執行一條簡單語句時只能使用到一條索引,注意這個限制;rows是傳回的結果集大小,結果集就是使用該索引進行一次搜尋的所有匹配結果;Extra一般會顯示查詢和排序的方式,。
如果沒有使用到key,或者rows很大而用到了filesort排序,一般都會影響到效率,例如:
mysql> desc select * from imgs where userid="7mini" order by clicks desc limit 10;
+----+-------------+-------+------+------------ ---+------+---------+------+-------+-------------- ---------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+- ------------+-------+------+---------------+------ +---------+------+-------+------------------------ -----+
| 1 | SIMPLE | imgs | ALL | NULL | NULL | NULL | NULL | 12506 | Using where; Using filesort |
+----+------- ------+-------+------+---------------+------+----- ----+------+-------+-----------------------------+
1 row in set (0.00 sec)
這條sql結果集會12506條,用到了filesort,所以執行起來會非常消耗效率的。這時mysql執行時會把整個表格掃描一遍,一條一條去找到符合userid="7mini"的記錄,然後還要對這些記錄的clicks進行一次排序,效率可想而知。真實執行時如果發現還比較快的話,那是因為伺服器內存還足夠將12506條比較短小的記​​錄全部讀入內存,所以還比較快,但是並發多起來或者表大起來的話,效率問題就嚴重了。
這時我把userid加入索引:
create index userid on imgs (userid);
然後再檢查:
mysql> desc select * from imgs where userid="7mini" order by clicks desc limit 10;
+----+-------------+-------+------+--------- ------+--------+---------+-------+------+--------- --------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+- ---+-------------+-------+------+---------------+- -------+---------+-------+------+----------------- ------------+
| 1 | SIMPLE | imgs | ref | userid | userid | 51 | const | 8 | Using where; Using filesort |
+----+ -------------+-------+------+---------------+----- ---+---------+-------+------+--------------------- --------+
1 row in set (0.00 sec)
嗯,這時可以看到mysql使用了userid這個索引搜尋了,用userid索引一次搜尋後,結果集有8條。然後雖然使用了filesort一條一條排序,但因為結果集只有區區8條,效率問題才得以緩解。
但是,如果我用別的userid查詢,結果又會有所不同:
mysql> desc select * from imgs where userid="admin" order by clicks desc limit 10;
+--- -+-------------+-------+------+---------------+--- -----+---------+-------+------+------------------- ----------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+------ -------+-------+------+---------------+--------+-- -------+-------+------+--------------------------- --+
| 1 | SIMPLE | imgs | ref | userid | userid | 51 | const | 2944 | Using where; Using filesort |
+----+---------- ---+-------+------+---------------+--------+------ ---+-------+------+-----------------------------+
1 row in set (0.00 sec)
這個結果和userid="7mini"的結果基本上相同,但是mysql用userid索引一次搜尋後結果集的大小達到2944條,這2944筆記錄都會加入記憶體進行filesort,效率比起7mini那次來說就差很多了。這時可以有兩種辦法可以解決,第一種辦法是再加一個索引和判斷條件,因為我只需要根據點擊量取最大的10條數據,所以有很多數據我根本不需要加進來排序,比如點擊量小於10的,這些數據可能佔了很大部分。
我對clicks加上索引,然後加入where條件再查詢:
create index clicks on imgs(clicks);
mysql> desc select * from imgs where userid="admin" order by clicks desc limit 10;
+----+-------------+-------+------+--------- ------+--------+---------+-------+------+--------- --------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+- ---+-------------+-------+------+---------------+- -------+---------+-------+------+----------------- ------------+
| 1 | SIMPLE | imgs | ref | userid,clicks | userid | 51 | const | 2944 | Using where; Using filesort |
+--- -+-------------+-------+------+---------------+--- -----+---------+-------+------+------------------- ----------+
1 row in set (0.00 sec)
這時可以看到possible_keys變成了userid,clicks,possible_keys是所有可以匹配的索引,mysql會從possible_keys中自己判斷並取用其中一個索引來執行語句,值得注意的是,mysql取用的這個索引未必是最優化的。這次查詢mysql還是使用userid這個索引來查詢的,並沒有按照我的意願,所以結果還是沒有什麼改變。改一下sql加上use index強制mysql使用clicks索引:
mysql> desc select * from imgs use index (clicks) where userid='admin' and clicks>10 order by clicks desc limit 10
+-- --+-------------+-------+-------+---------------+- -------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------- +-------+---------------+--------+---------+------ +------+-------------+
| 1 | SIMPLE | imgs | range | clicks | clicks | 4 | NULL | 5455 | Using where |
+----+-------------+-------+-------+-------------- -+--------+---------+------+------+-------------+
1 row in set (0.00 sec)
這時mysql用到了clicks索引進行查詢,但是結果集比userid還要大!看來還要再進行限制:
mysql> desc select * from imgs use index (clicks) where userid='admin' and clicks>1000 order by clicks desc limit 10
+----+-------------+------ -+-------+---------------+--------+---------+----- -+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+-------------- -+--------+---------+------+------+-------------+
| 1 | SIMPLE | imgs | range | clicks | clicks | 4 | NULL | 312 | Using where |
+----+-------------+--- ----+-------+---------------+--------+---------+-- ----+------+-------------+
1 row in set (0.00 sec)
加到1000的時候結果集變成了312條,排序效率應該是可以接受。
不過,採用換索引這種最佳化方式需要取一個取樣點,例如這個例子中的1000這個數字,這樣,對userid的每個數值,都要去找一個取樣點,這樣對程式來說是很難辦的。如果以1000取樣的話,那麼userid='7mini'這個例子中,取到的結果將不會是8條,而是2條,給用戶造成了困惑。
當然還有另一個方法,加入雙重索引:
create index userid_clicks on imgs (userid, clicks)
mysql> desc select * from imgs where userid="admin" order by clicks desc limitcli 10 ;
+----+-------------+-------+------+----------- -----------+---------------+---------+-------+---- --+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+ -------------+-------+------+--------------------- -+---------------+---------+-------+------+------- ------+
| 1 | SIMPLE | imgs | ref | userid,userid_clicks | userid_clicks | 51 | const | 2944 | Using where |
+----+------- ------+-------+------+----------------------+----- ----------+---------+-------+------+-------------+
1 row in set (0.00 sec)
這時可以看到,結果集還是2944條,但是Extra中的filesort不見了。這時mysql使用userid_clicks這個索引去查詢,這不但能快速查詢到userid="admin"的所有記錄,並且結果是根據clicks排好序的!所以不用再把這個結果集讀入內存一條一條排序了,效率上會高很多。
但是用多字段索引這種方式有個問題,如果查詢的sql種類很多的話,就得好好規劃一下了,否則索引會建得非常多,不但會影響到數據insert和update的效率,而且資料表也容易損壞。
以上是對索引優化的辦法,因為原因可能會比較複雜,所以寫得比較的長,一般好好優化了索引之後,mysql的效率會提升n個檔次,從而也不需要考慮增加機器來解決問題了。
但是,mysql甚至所有資料庫,可能都不好解決limit的問題。在mysql中,limit 0,10只要索引合適,是沒有問題的,但是limit 100000,10就會很慢了,因為mysql會掃描排好序的結果,然後找到100000這個點,取出10個回傳。要找到100000這個點,就要掃描100000筆記錄,這個循環是比較耗時的。不知道會不會有什麼好的演算法可以優化這個掃描引擎,我冥思苦想也想不出有什麼好方法。對於limit,目前直至比較久遠的將來,我想只能透過業務、程序和資料表的規劃來優化,我想到的這些優化辦法也都還沒有一個是萬全之策,往後再討論。
2、sql寫法過於複雜
sql寫法假如用到一些特殊的功能,比如groupby、或者多表聯合查詢的話,mysql用到什麼方式來查詢也可以用desc來分析,我這邊用複雜sql的情況還不算多,所以不常分析,暫時就沒有好的建議。
3、設定錯誤
配置裡主要參數是key_buffer、sort_buffer_size/myisam_sort_buffer_size,這兩個參數意思是:
key_buffer=128M:全部表的索引都會盡可能放在這塊記憶體區域內,索引比較大的話就開稍大點都可以,我一般設為128M,有個好的建議是把很少用到並且比較大的表想辦法移到別的地方去,這樣可以顯著減少mysql的內存佔用。
sort_buffer_size=1M:單一線程使用的用於排序的內存,查詢結果集都會放進這內存裡,如果比較小,mysql會多放幾次,所以稍微開大一點就可以了,重要是優化好索引和查詢語句,讓他們不要產生太大的結果集。
其他設定:
thread_c
interactive_timeout=30
wait_timeout=30:這兩個設定使用10-30秒就可以了,這樣會盡快釋放記憶體資源,注意:一直在使用的連接是不會斷掉的,這個配置只是斷掉了長時間不動的連接。
query_cache:這個功能不要使用,現在很多人看到cache這幾個字母就像看到了寶貝,這是不唯物主義的。 mysql的query_cache在每次表資料有變化的時候都會重新清理連至該表的所有緩存,如果更新比較頻繁,query_cache不但幫不上忙,而且還會對效率影響很大。這個參數只適合只讀型的資料庫,如果非要用,也只能用query_cache_type=2自行用SQL_CACHE指定一些sql來快取。
max_connections:預設為100,一般情況下是足夠用的,但是一般要開大一點,開到400-600就可以了,能超過600的話一般就有效率問題,得另找對策,光靠增加這個數字不是辦法。
其它配置可以按預設就可以了,個人覺得問題還不是那麼的大,提醒一下:1、配置雖然很重要,但是在絕大部分情況下都不是效率問題的罪魁禍首。 2、mysql是一個資料庫,對於資料庫最重要考究的不應是效率,而是穩定性和資料準確性。
4、機器實在負荷不了
如果做了以上調整,伺服器還是不能承受,那就只能透過架構級調整來優化了。
1、mysql同步。
透過mysql同步功能將資料同步到數台從資料庫,由主資料庫寫入,從資料庫提供讀取。
我個人不是那麼樂意使用mysql同步,因為這個辦法會增加程式的複雜性,常常會造成資料方面的錯誤。在高負載的服務中,當機了還可以快速重啟,但資料錯誤的話要恢復就比較麻煩。
2、加入快取
加入快取之後,就可以解決並發的問題,效果很明顯。如果是即時系統,可以考慮用刷新快取方式讓快取保持最新。
在前端加入squid的架構比較提倡使用,在命中率比較高的應用中,基本上可以解決問題。
如果是在程式邏輯層裡面進行緩存,會增加很多複雜性,問題會比較多而且難解決,不建議在這一層面進行調整。
3、程式架構調整,支援同時連接多個資料庫
如果web加入快取後問題還是比較嚴重,只能透過程式架構調整,把應用程式拆散,用多台的機器同時提供服務。
如果拆散的話,對業務是有少許影響,如果業務當中有部分功能必須使用所有的數據,可以用一個完整庫+n個分散庫這樣的架構,每次修改都在完整庫和分散庫各操作一次,或定期整理完整庫。
當然,還有一種最笨的,把資料庫整個完整的做拷貝,然後程式每次都把完整的sql在這些庫執行一遍,訪問時輪詢訪問,我認為這樣要比mysql同步的方式安全。
4、使用mysql proxy 代理
mysql proxy 可以透過代理把資料庫中的各個表分散到數台伺服器,但是它的問題是沒有能解決熱門表的問題,如果熱門內容散在多個表中,用這個方法是比較輕鬆就能解決問題。
我沒有用過這個軟體也沒有認真查過,不過我對它的功能有一點點懷疑,就是它怎麼實現多個表之間的聯合查詢?如果能實現,那麼效率如何呢?
5.使用memcachedb
資料庫換用支援mysql的memcachedb,是可以一試的想法,從memcachedb的實作方式和層面來看對資料沒有什麼影響,不會對使用者有什麼困擾。
為我現在因為資料庫方面問題不多,沒有試驗過這個玩意。不過,只要它支援mysql的大部分主要的語法,而且本身穩定,可用性是無需置疑的。

以上就介紹了my summer holiday英文作文 mysql 效能的檢查與最佳化方法,包括了my summer holiday英文作文的內容,希望對PHP教學有興趣的朋友有所幫助。

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
PHP的目的:構建動態網站PHP的目的:構建動態網站Apr 15, 2025 am 12:18 AM

PHP用於構建動態網站,其核心功能包括:1.生成動態內容,通過與數據庫對接實時生成網頁;2.處理用戶交互和表單提交,驗證輸入並響應操作;3.管理會話和用戶認證,提供個性化體驗;4.優化性能和遵循最佳實踐,提升網站效率和安全性。

PHP:處理數據庫和服務器端邏輯PHP:處理數據庫和服務器端邏輯Apr 15, 2025 am 12:15 AM

PHP在數據庫操作和服務器端邏輯處理中使用MySQLi和PDO擴展進行數據庫交互,並通過會話管理等功能處理服務器端邏輯。 1)使用MySQLi或PDO連接數據庫,執行SQL查詢。 2)通過會話管理等功能處理HTTP請求和用戶狀態。 3)使用事務確保數據庫操作的原子性。 4)防止SQL注入,使用異常處理和關閉連接來調試。 5)通過索引和緩存優化性能,編寫可讀性高的代碼並進行錯誤處理。

您如何防止PHP中的SQL注入? (準備的陳述,PDO)您如何防止PHP中的SQL注入? (準備的陳述,PDO)Apr 15, 2025 am 12:15 AM

在PHP中使用預處理語句和PDO可以有效防範SQL注入攻擊。 1)使用PDO連接數據庫並設置錯誤模式。 2)通過prepare方法創建預處理語句,使用佔位符和execute方法傳遞數據。 3)處理查詢結果並確保代碼的安全性和性能。

PHP和Python:代碼示例和比較PHP和Python:代碼示例和比較Apr 15, 2025 am 12:07 AM

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

PHP行動:現實世界中的示例和應用程序PHP行動:現實世界中的示例和應用程序Apr 14, 2025 am 12:19 AM

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP:輕鬆創建交互式Web內容PHP:輕鬆創建交互式Web內容Apr 14, 2025 am 12:15 AM

PHP可以輕鬆創建互動網頁內容。 1)通過嵌入HTML動態生成內容,根據用戶輸入或數據庫數據實時展示。 2)處理表單提交並生成動態輸出,確保使用htmlspecialchars防XSS。 3)結合MySQL創建用戶註冊系統,使用password_hash和預處理語句增強安全性。掌握這些技巧將提升Web開發效率。

PHP和Python:比較兩種流行的編程語言PHP和Python:比較兩種流行的編程語言Apr 14, 2025 am 12:13 AM

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP的持久相關性:它還活著嗎?PHP的持久相關性:它還活著嗎?Apr 14, 2025 am 12:12 AM

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中