MySQL 的效能優化最佳實踐

2021-08-11 15:33:48 字數 4578 閱讀 5396

資料庫操作是當今 web 應用程式中的主要瓶頸。 不僅是 dba(資料庫管理員)需要為各種效能問題操心,程式設計師為做出準確的結構化表,優化查詢效能和編寫更優**,也要費盡心思。 在本文中,我列出了一些針對程式設計師的 mysql 優化技術。

在我們開始學習之前,我補充一點:你可以在 envato market 上找到大量的 mysql 指令碼和實用程式。

大部分mysql伺服器都有查詢快取功能。這是提高效能的最有效的方法之一,這是由資料庫引擎私下處理的。當同乙個查詢被多次執行,結果會直接從快取裡提取,這樣速度就很快。

主要的問題是,這對程式設計師來說太簡單了,不容易看到,我們很多人都容易忽略。我們實際上是可以組織查詢快取執行任務的。

// query cache doesnotwork

$r = mysql_query("select username from user where signup_date >= curdate()");

// query cache works!

$today =date("y-m-d");

$r = mysql_query("select username from user where signup_date >= '$today'");

查詢快取在第一行不執行的原因在於curdte()功能的使用。這適用於所有的非確定性功能,就像now()和rand()等等。因為功能返回的結果是可變的。mysql決定禁用查詢器的查詢快取。我們所需要做的是通過新增一額外一行php,在查詢前阻止它發生。

現在它只會從表2裡面掃瞄9和16行,而非掃瞄7883行。經驗法則是乘以所有「行」那一欄的數字,你的查詢效能會跟結果數字成比例的。

有時當你查表時,你已經知道你正在查詢的結果只有一行。你可能正在獲取唯一記錄,或者你可能只是查詢是否存在滿足你的where子句條件的記錄。

在這種情況下,將limit 1新增到查詢條件中可以提高效能。這樣,資料庫引擎將在找到剛剛第乙個記錄之後停止掃瞄記錄,而不是遍歷整個表或索引。

1

2

3

4

5

6

7

8

$r = mysql_query("select * from user where state = 'alabama'");

if (mysql_num_rows($r) > 0)

$r = mysql_query("select 1 from user where state = 'alabama' limit 1");

if (mysql_num_rows($r) > 0)

索引不僅僅是為了主鍵或唯一鍵。如果你會在你的表中按照任何列搜尋,你就都應該索引它們。

如果你的應用程式包含許多連線查詢, 你需要確保連線的字段在兩張表上都建立了索引。 這會影響mysql如何內部優化連線操作。

此外,被連線的字段,需要使用同樣型別。例如, 如果你使用乙個decimal欄位, 連線另一張表的int欄位, mysql將無法使用至少乙個索引。 即使字元編碼也需要使用相同的字元型別。

1

2

3

$r = mysql_query("select company_name from users

left join companies on (users.state = companies.state)

where users.id = $user_id");

起初這是乙個聽起來挺酷的技巧, 讓許多菜鳥程式設計師陷入了這個陷阱。但你可能不知道,一旦你開始在查詢中使用它,你建立了非常可怕的查詢瓶頸。

如果你真的需要對結果隨機排序, 這有乙個更好的方法。補充一些額外**,你將可以防止當資料成指數級增長時造成的瓶頸。關鍵問題是,mysql必須在排序之前對錶中的每一行執行rand()操作(這需要處理能力),並且僅僅給出一行。

1

2

3

4

5

$r = mysql_query("select username from user order by rand() limit 1");

$r = mysql_query("select count(*) from user");

$d = mysql_fetch_row($r);

$rand = mt_rand(0,$d[0] - 1);

$r = mysql_query("select username from user limit $rand, 1");

所以挑選乙個小於結果數的隨機數,並將其用作limit子句中的偏移量。

從資料表中讀取的資料越多,查詢操作速度就越慢。它增加了磁碟操作所需的時間。此外,當資料庫伺服器與web伺服器分開時,由於必須在伺服器之間傳輸資料,將會有更長的網路延遲。

這是乙個好習慣:當你使用select語句時總是指定你需要的列。

1

2

3

4

5

6

$r= mysql_query("select * from user where user_id = 1");

$d= mysql_fetch_assoc($r);

echo"welcome ";

$r= mysql_query("select username from user where user_id = 1");

$d= mysql_fetch_assoc($r);

echo"welcome ";

在每個以id列為primary key的資料表中,優先選擇auto_increment或者int。 也可以優選使用unsigned,因為該值不能為負的。

即使你擁有乙個具有唯一使用者名字段的使用者表,也不要將其作為主鍵。 varchar欄位作為主鍵(檢索)速度較慢。通過內部id引用所有的使用者資料,你的**中將更加結構化。

有些後台操作是由mysql引擎本身完成的,它在內部使用主鍵字段。當資料庫設定越複雜(集群,分割槽等…),這就變得更加重要了。

這個規則的乙個可能的例外是「關聯表」,用於兩個表之間的多對多型別的關聯。例如,「posts_tags」表中包含兩列:post_id,tag_id,用於儲存表名為「post」和「tags」的兩個表之間的關係。這些表可以具有包含兩個id欄位的primary鍵。

enum列舉型別是非常快速和緊湊的。在內部它們像tinyint一樣儲存,但它們可以包含和顯示字串值。這使他們成為某些領域的完美候選。

如果有乙個欄位只包含幾種不同的值,請使用enum而不是varchar。例如,它可以是名為「status」的列,並且只包含諸如「active」,「inactive」,「pending」,「expired」等的值…

關於如何重構你的資料表,甚至有一種方法是可以從mysql本身得到「建議」。 當你有乙個varchar欄位,它實際上建議你將該列型別更改為enum。這通過呼叫procedure analyze()來完成。

procedure analyse() 將使用mysql分析列結構和表中的實際資料,為你提供一些建議。它只有在資料表中有實際資料時才有用,因為這在分析決策時很重要。

例如,如果你建立了乙個int型別的主鍵,但沒有太多行,mysql則可能建議您改用mediumint。或者如果你使用varchar欄位,如果表裡只有很少的取值,你可能會得到乙個建議是將其轉換為enum。

你也可以在其中乙個表檢視中單擊phpmyadmin中的「建議表結構」鏈結來執行此操作。

請記住,這些只是建議。 如果你的資料表變得越來越大,他們甚至可能不是正確的建議。至於如何修改最終是你來決定。

MySQL效能優化的21個最佳實踐

今天,資料庫的操作越來越成為整個應用的效能瓶頸了,這點對於web應用尤其明顯。關於資料庫的效能,這並不只是dba才需要擔心的事,而這更是我們程式設計師需要去關注的事情。當我們去設計資料庫表結構,對運算元據庫時 尤其是查表時的sql 具體可以參考 inet aton和inet ntoa 15.固定長度...

最佳實踐React效能優化

1 基本使用 使用方法 import react,from react import from utils const loadinghome dynamic import components home const loadinguser dynamic import components use...

JS最佳實踐 效能優化

首先,由於js是一種解釋型語言,執行速度要比編譯型語言慢得多。注 chrome是第一款內建優化引擎,將js編譯成本地 的瀏覽器,其它瀏覽器也陸續實現了js的編譯過程。但是,即使到了編譯執行js的新階段,仍然會存在低效率的 以下總結一些可以改進 的整體效能的方法。記住一點,隨著作用域中的作用域數量的增...