這篇文章為大家帶來了關於mysql的相關知識,其中主要介紹了關於索引大幅優化某PHP應用性能的相關內容,下面一起來看一下,希望對大家有幫助。
前兩個月某朋友要做一個項目,本著快速上線推廣的目的,直接購買了某公司的原始碼並讓賣家部署上線。看到原始碼後,我直接對朋友說:算是被小坑了,這個源碼品質有點差,用戶數起來後可能會有比較嚴重的效能問題。
做出這樣的評價,我是有依據的:
作為近乎即時應用,核心程式碼用PHP編寫,透過資料庫表記錄控制許多場景的並發和重複請求;
PHP開發不是問題,但對方工程師似乎不知道有CLI模式,而是透過計畫任務(crontab)達到程式不停運轉,於是乎浩浩蕩蕩幾十個curl計畫任務每分鐘執行;
#程式碼中有不少class1.php,像 class1-1.php這樣複製備份的文件,一眼看過去很難知曉其存在目的;
存在不少for迴圈讀取資料庫的程式碼,命名規則混亂。
當然,能賺錢的程式碼才是好程式碼(對方就透過這些程式碼賺錢了),我也沒多去糾結。最初的想法是,4核8G的配置,跑1萬個客戶應該很難,跑5000就可以了。
就在這週,忽然頻繁接到 阿里雲 的警報簡訊和郵件,說CPU佔用過高。心想市場推廣很順利,用戶大增嗎?一問朋友,才不到300個用戶!
這時才意識到,這套程式碼實際表現比我想想中的更差,有嚴重的效能問題。依照這個資源消耗速度,升級硬體是無底洞,效能優化才是正途。
拿到程式碼兩個月了,閒暇時間偶爾會看一下,已經大體知道其結構和主要功能。現在出現了嚴重效能問題,是時候嘗試做一些效能優化了。
鑑於數十個計畫任務不停運行,其不斷驅動系統運轉,因此計畫任務的相關功能是最先被了解的。根據自己的理解,先暫停了二十多個已經不需要的計畫任務。暫停無用計畫任務後,系統整體CPU使用率下降到了60%多,煩人的提醒簡訊和郵件終於消停了。等待了一天,朋友也沒有回饋有功能受影響,顯示思路和出手點都正確。
但是200多個用戶就這麼消耗資源,一定還有什麼地方不對勁。今天有空又登入伺服器,執行top指令,發現mysql進程一直佔據200%多的CPU資源。看過原始碼的我知道MySQL佔用高是有原因的而且是可能的,但還是想看看為什麼這麼耗資源。
登入MySQL伺服器,查看是否開啟了slow log:show variables like '%slow%';,發現開啟了慢查詢日誌:
接著檢視日誌,查到某條sql語句一直出現在日誌中:
可以看到,執行這條sql語句掃描了38萬多行記錄。語句涉及的兩張表一張有600多筆記錄,另一張4萬多筆記錄,相當於全表掃描了4萬多的表好幾次,怪不得特別慢。
接著檢查兩個表的索引,除了自增id作為主鍵外,沒有建立其他索引。使用explain執行語句,顯示沒有使用任何索引:
接下來,在兩個表上分別就查詢條件的uid、session_id列上建立索引。索引建立完成後,肉眼可見的CPU佔用率和系統負載都降下來了。再次使用explain執行查詢語句,索引資訊已經用上了,掃描行數大大減少:
經過上面的最佳化,目前應用的總體CPU佔用率在5%左右,MySQL的CPU佔用率大約是15%,系統負載從4降到了0.3。終於暫時不用擔心效能問題了,就算伺服器配置降到1核心CPU也能撐得住。
進一步查看程式碼並結合日誌,建立索引和修改部分查詢語句,CPU佔用率降到6%左右,終於暫時不用擔心效能問題了
工程師在開發工程中,不僅要寫出「能用」的程式碼,還要寫出「好用」的程式碼。本例中透過建立兩個索引就能大幅提升系統效能,便是讓程式碼從「能用」轉到「好用」。
本文提到的效能最佳化偏運維,程式碼中的效能最佳化暫時還未觸碰。但一個整體的原則是不會錯的:多使用緩存,盡可能的減少慢IO設備的同步讀取。
以上是建立MySQL索引大幅優化某PHP應用效能的詳細內容。更多資訊請關注PHP中文網其他相關文章!