2019/3/16 10:48:36
如(rú)果隻是少(shǎo)量的(de)頁面訪問有(yǒu)問題(性能(néng)問題)時,優化是非常簡單的(de)。如(rú)果是“所有(yǒu)的(de)都(dōu)慢(màn)”,需要如(rú)何做呢?
看那些來自于數據庫并且在頁面上(shàng)顯示的(de)信息。這是重要的(de),因爲這些信息是需要用(yòng)這樣或那樣的(de)方法從數據庫中讀(dú)取出來的(de),如(rú)果确實是打算這樣顯示的(de)話(huà)。任務就是要使用(yòng)最高(gāo)效的(de)方法,從數據庫中得到(dào)這些信息。
考查這些信息的(de)動态性。如(rú)果很少(shǎo)改變,或者幹脆就是靜态的(de),那麽比較好的(de)方法是預先創建(pre-create)或者緩存(http: //www.mysqlperformanceblog.com/2006/08/09/cache-performance-comparison/)它。有(yǒu)非常多的(de)緩存和(hé)預建技術(shù)(http://www.mysqlperformanceblog.com/2006/08/08/caching- techinques/)可(kě)以使用(yòng)。隻是要記住,優化數據庫訪問的(de)最好的(de)方法,就是避免訪問數據庫。這對于其他(tā)的(de)類似事情也(yě)适用(yòng)----如(rú)果可(kě)以完全避免動态頁面的(de)産生,并且使用(yòng)服務器(qì)的(de)緩存來解決,就更好了。
檢查從數據庫讀(dú)出的(de)數據與需要顯示的(de)信息是否相(xiàng)符。從數據庫出讀(dú)取的(de)信息,往往比生成頁面所需要的(de)信息要多。輕一點的(de)像是SELECT * FROM tbl,而不是隻列出那些真正需要的(de)列;嚴重的(de)可(kě)以是用(yòng)SELECT * FROM tbl來計(jì)算表中有(yǒu)多少(shǎo)行(xíng)記錄(不是開(kāi)玩笑(xiào))。有(yǒu)時候會(huì)看到(dào)查詢了100個(gè)stories,其中任一個(gè)會(huì)被選擇顯示出來,由應用(yòng)程序層做過濾。有(yǒu)時候在應用(yòng)程序層這樣做是高(gāo)效的(de),但(dàn)是通常應該使查詢隻返回需要的(de)信息。
檢查結果集的(de)記錄數。這是非常重要、而且經常被遺忘的(de)步驟。如(rú)果一個(gè)查詢返回很少(shǎo)的(de)行(xíng)數,有(yǒu)些人(rén)就認爲它是簡單的(de),而真正重要的(de)是這個(gè)查詢分(fēn)析了多少(shǎo)行(xíng)數據。比如(rú)SELECT COUNT(*) FROM links WHERE domain='mysql.com'; 隻返回一行(xíng),但(dàn)卻掃描了成千上(shàng)萬的(de)記錄(或者索引節點)。其他(tā)通常的(de)殺手查詢是GROUP BY查詢和(hé)SORT查詢 ---- SELECT name,descr FROM titles ORDER BY rank DESC LIMIT 10 ----如(rú)果沒有(yǒu)适當的(de)索引,就會(huì)使用(yòng)“filesort”,會(huì)有(yǒu)些問題。此外就是JOIN(關聯)---- 關聯是高(gāo)代價的(de)(當然是相(xiàng)對的(de)),并且确實增加了爲了産生結果集而使用(yòng)的(de)數據量 ---- 如(rú)果不得不關聯10個(gè)表來組合出想要的(de)結果,那麽會(huì)比從一個(gè)表中得到(dào)同樣的(de)數據要慢(màn)很多。
檢查結果集的(de)生成實際需要的(de)記錄數。有(yǒu)時查詢需要使用(yòng)大(dà)量數據來産生結果集,是因爲沒有(yǒu)适當的(de)索引 ---- 這是容易發生的(de)。比如(rú)我們的(de)ORDER BY rank 查詢就是這樣 ---- 爲rank列增加索引,會(huì)使這個(gè)查詢僅使用(yòng)10行(xíng)數據來返回10行(xíng) ---- 恰恰是我們想要的(de)。然而我們的(de)COUNT(*)查詢是不同的(de) ---- 即使在domain列上(shàng)有(yǒu)索引,它仍然需要掃描很多行(xíng)數據來得到(dào)結果集。這樣的(de)查詢需要重新設計(jì),而不是簡單地(dì)調整 ---- 比如(rú)彙總表(summary table)保存了每個(gè)域的(de)link數量,就可(kě)以解決。
檢查查詢的(de)次數。如(rú)果可(kě)以使用(yòng)一個(gè)查詢得到(dào)所需要的(de)數據,那麽就好于用(yòng)多個(gè)查詢得到(dào)同樣的(de)數據,前提是這一個(gè)查詢不會(huì)因爲與那些查詢優化方式不同而需要分(fēn)析更多行(xíng)的(de)數據。這裏一個(gè)典型的(de)例子是SELECT * FROM tbl WHERE id=5 執行(xíng)了很多次,每次使用(yòng)不同的(de)常量 ---- 用(yòng)類似 IN(5,7,4,56) 來替換是非常有(yǒu)效的(de)。但(dàn)也(yě)不要被這樣的(de)方法迷住。我曾經看到(dào)有(yǒu)人(rén)嘗試用(yòng)UNION(需要适當填充以使不同的(de)字段數目及類型能(néng)夠匹配)連接所有(yǒu)的(de)查詢--- -這不是個(gè)好主意。然而,如(rú)果可(kě)以減小(xiǎo)查詢的(de)次數,而又(yòu)不會(huì)增加應用(yòng)程序架構的(de)複雜性,那麽是值得做的(de)。
深圳市南山區南山街(jiē)道南海(hǎi)大(dà)道西(xī)桂廟路(lù)北陽光(guāng)華藝大(dà)廈1棟4F、4G-04
咨詢電話(huà):136 8237 6272
大(dà)客戶咨詢:139 0290 5075
業(yè)務QQ:195006118
技術(shù)QQ:179981967