如何編寫高效能的PHP代碼(1)

來源:互聯網
上載者:User

 

資料庫最佳化技巧,你中做到了哪些:

 

·         使用持久的串連資料庫以避免串連開銷。如果不能使用持久的串連並且你正啟動許多新的與資料庫的串連,可能要更改thread_cache_size變數的值。參見7.5.2節,“調節伺服器參數”。

·         總是檢查所有查詢確實使用已經在表中建立了的索引。在MySQL中,可以用EXPLAIN命令做到。參見7.2.1節,“EXPLAIN文法(擷取關於SELECT的資訊)”。

·         嘗試避免在頻繁更新的表上執行複雜的SELECT查詢,以避免與鎖定表有關的由於讀、寫衝突發生的問題。

·         對於沒有刪除的行的MyISAM表,可以在另一個查詢正從表中讀取的同時在末尾插入行。如果這很重要,應考慮按照避免刪除行的方式使用表。另一個可能性是在刪除大量行後運行OPTIMIZE TABLE。參見15.1節,“MyISAM儲存引擎”。

·         要修複任何ARCHIVE表可以發生的壓縮問題,可以執行OPTIMIZE TABLE。參見15.8節,“ARCHIVE儲存引擎”。

·         如果你主要按expr1,expr2,...順序檢索行,使用ALTER TABLE ... ORDER BY expr1, expr2, ...。對錶大量更改後使用該選項,可以獲得更好的效能。

·         在一些情況下,使得基於來自其它表的列的資訊引入一個“ 雜湊”的列有意義。如果該列較短並且有合理的唯一值,它可以比在許多列上的一個大索引快些。在MySQL中,很容易使用這個額外列:

·                SELECT * FROM tbl_name
·                     WHERE hash_col=MD5(CONCAT(col1,col2))
·                     AND col1='constant' AND col2='constant';

·         對於頻繁更改的MyISAM表,應試圖避免所有變長列(VARCHAR、BLOB和TEXT)。如果表包括單一的變長列則使用動態記錄格式。參見第15章:儲存引擎和表類型。

·         只是因為行太大,將一張表分割為不同的表一般沒有什麼用處。為了訪問行,最大的效能衝擊是磁碟搜尋以找到行的第一個位元組。在找到資料後,大多數新型磁碟對大多數應用程式來說足夠快,能讀入整個行。確實有必要分割的唯一情形是如果它是使用動態記錄格式使之變為固定的記錄大小的MyISAM表(見上述),或如果你需要很頻繁地掃描表而不需要大多數列。參見第15章:儲存引擎和表類型。

·         如果你需要很經常地計算結果,例如基於來自很多行的資訊的計數,引入一個新表並即時更新計數器可能更好一些。下面形式的更新會更快一些:

UPDATE tbl_name SET count_col=count_col+1 WHERE key_col=constant;

當你使用象MyISAM那樣的只有表級鎖定的MySQL儲存引擎(多重讀/單個寫)時,這確實很重要。這也給大多數資料庫較好的效能,因為行鎖定管理器在這種情況下有較少的事情要做。

·         如果你需要從大的記錄檔案表中收集統計資訊,使用總結性的表而不是掃描整個表。維護總結應該比嘗試做“即時”統計要快些。當有變化時從日誌重建新的總結表比改變啟動並執行應用(取決於業務決策)要快得多。 如果可能,應該將報告分類為“即時”或“統計”,這裡統計報告所需的資料僅僅基於從實際資料定期產生的總結表中產生。 充分利用列有預設值的事實。只有當插入的值不同於預設值時,才明確地插入值。這減少MySQL需要做的文法分析從而提高插入速度。 在一些情況下,封裝並儲存資料到一個BLOB列中是很方便的。在這種情況下,必須在你的應用中增加額外的代碼來打包/解包資訊,但是這種方法可以在某些階段節省很多訪問。當有不符合行和列表結構的資料時,這很實用。 在一般情況下,應該嘗試以非冗餘方式(查看資料庫理論中的第三正則形式)儲存資料,但是為了獲得更快的速度,可以複製資訊或建立總結表。 預存程序或UDF(使用者定義函數)可能是獲得更好效能的一個好方法,詳細資料參見第20章:儲存程式和函數和27.2節,“為MySQL添加新函數”。 總是能通過在應用程式中緩衝查詢/答案並嘗試同時執行很多插入/更新來獲得一些好處。如果資料庫支援鎖定表(象MySQL和Oracle),這應該有助於確保索引緩衝只在所有更新後重新整理一次。還可以利用MySQL的查詢快取來獲得類似的結果;參見5.13節,“MySQL查詢高速緩衝”。 當不需要知道何時寫入資料時,使用INSERT DELAYED。這樣可以加快處理,因為很多記錄可以通過一次磁碟寫入被寫入。 當你想要讓選擇顯得更重要時,使用INSERT /*! LOW_PRIORITY */。 使用INSERT LOW_PRIORITY來取得插入隊列的檢索,也就是即使有另一個客戶等待寫入也要執行SELECT。 使用多行INSERT語句通過一個SQL命令來儲存很多行(許多SQL伺服器支援它,包括MySQL)。 使用LOAD DATA INFILE裝載較大數量的資料。這比使用INSERT要快得多。 使用AUTO_INCREMENT列構成唯一值。 當MyISAM使用動態表格式時,偶爾使用OPTIMIZE TABLE可以避免片段。參見15.1.3節,“MyISAM表的儲存格式”。 可能時使用MEMORY表以得到更快的速度。參見15.4節,“MEMORY (HEAP)儲存引擎”。 在Web伺服器中,圖象和其它二進位資產應該作為檔案儲存體。也就是僅在資料庫中儲存的本檔案的引用而不是檔案本身。大多數Web伺服器在快取檔案方面比資料庫內容要好得多,因此使用檔案一般要快得多。 對經常訪問的不重要資料(如為沒有在網頁瀏覽器中啟用cookie的使用者最後顯示的標語的相關資訊)使用記憶體表。在許多Web應用程式環境中也可以使用使用者會話來處理可變狀態資料。 在不同表中具有相同資訊的列應該被聲明為相同的並有相同的名字。嘗試使名字簡單化。例如,在customer表中使用name而不是customer_name。為了使名字能移植到其它SQL伺服器,應該使名字短於18個字元。 如果確實需要很高的速度,應該研究一下不同SQL伺服器支援的資料存放區的低層介面。例如直接存取MySQL MyISAM儲存引擎,比起使用SQL介面,速度可以提高2-5倍。為了能實現,資料必須與應用程式在同一台伺服器上,並且通常只應該被一個進程訪問(因為外部檔案鎖定確實很慢)。通過在MySQL伺服器中引進低層MyISAM命令能消除以上問題(如果需要,這可能是獲得更好效能的一個簡單的方法)。通過精心設計資料庫介面,應該能相當容易地支援這類最佳化。 如果正使用數字資料,在許多情況下,從一個資料庫訪問資訊(使用即時串連)比訪問一個文字檔快些。這是因為資料庫中的資訊比文字檔更緊湊,因此這將涉及更少的磁碟訪問。還可以在應用程式中節省代碼,因為不須分析文字檔來找出行和列的邊界。

·         通過複製可以提高某些操作的效能。可以在複製伺服器中分布客戶的檢索以均分負載。為了防止備份時主伺服器變慢,可以使用一個從伺服器來備份。參見第6章:MySQL中的複製。

·         用DELAY_KEY_WRITE=1選項聲明MyISAM表可以使索引更新更快,因為在表關閉之前它們不重新整理到硬碟上。不利之處是當表開啟時如果殺掉伺服器,應確保用--myisam-recover選項運行伺服器保證沒有問題,或者在重啟伺服器之前運行myisamchk。(然而,即使在這種情況下,應通過使用DELAY_KEY_WRITE保證不遺失資料,因為關鍵字資訊總是可以從資料行產生)。

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.