程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> MySQL性能優化的最佳20+條經驗(1)

MySQL性能優化的最佳20+條經驗(1)

編輯:MySQL綜合教程

MySQL性能優化的最佳20+條經驗(1)


今天,數據庫的操作越來越成為整個應用的性能瓶頸了,這點對於Web應用尤其明顯。關於數據庫的性能,這並不只是DBA才需要擔心的事,而這更是我 們程序員需要去關注的事情。當我們去設計數據庫表結構,對操作數據庫時(尤其是查表時的SQL語句),我們都需要注意數據操作的性能。這裡,我們不會講過 多的SQL語句的優化,而只是針對MySQL這一Web應用最多的數據庫。希望下面的這些優化技巧對你有用。

1. 為查詢緩存優化你的查詢

大多數的MySQL服務器都開啟了查詢緩存。這是提高性最有效的方法之一,而且這是被MySQL的數據庫引擎處理的。當有很多相同的查詢被執行了多次的時候,這些查詢結果會被放到一個緩存中,這樣,後續的相同的查詢就不用操作表而直接訪問緩存結果了。

這裡最主要的問題是,對於程序員來說,這個事情是很容易被忽略的。因為,我們某些查詢語句會讓MySQL不使用緩存。請看下面的示例:

  1. // 查詢緩存不開啟 
  2. $r = mysql_query("SELECT username FROM user WHERE signup_date >= CURDATE()"); 
  3.  // 開啟查詢緩存 
  4. $today = date("Y-m-d"); 
  5. $r = mysql_query("SELECT username FROM user WHERE signup_date >= '$today'"); 

上面兩條SQL語句的差別就是 CURDATE() ,MySQL的查詢緩存對這個函數不起作用。所以,像 NOW() 和 RAND() 或是其它的諸如此類的SQL函數都不會開啟查詢緩存,因為這些函數的返回是會不定的易變的。所以,你所需要的就是用一個變量來代替MySQL的函數,從而 開啟緩存。

2. EXPLAIN 你的 SELECT 查詢

使用 EXPLAIN 關鍵字可以讓你知道MySQL是如何處理你的SQL語句的。這可以幫你分析你的查詢語句或是表結構的性能瓶頸。

EXPLAIN 的查詢結果還會告訴你你的索引主鍵被如何利用的,你的數據表是如何被搜索和排序的……等等,等等。

挑一個你的SELECT語句(推薦挑選那個最復雜的,有多表聯接的),把關鍵字EXPLAIN加到前面。你可以使用phpmyadmin來做這個事。然後,你會看到一張表格。下面的這個示例中,我們忘記加上了group_id索引,並且有表聯接:

當我們為 group_id 字段加上索引後:

我們可以看到,前一個結果顯示搜索了 7883 行,而後一個只是搜索了兩個表的 9 和 16 行。查看rows列可以讓我們找到潛在的性能問題。

3. 當只要一行數據時使用 LIMIT 1

當你查詢表的有些時候,你已經知道結果只會有一條結果,但因為你可能需要去fetch游標,或是你也許會去檢查返回的記錄數。

在這種情況下,加上 LIMIT 1 可以增加性能。這樣一樣,MySQL數據庫引擎會在找到一條數據後停止搜索,而不是繼續往後查少下一條符合記錄的數據。

下面的示例,只是為了找一下是否有“中國”的用戶,很明顯,後面的會比前面的更有效率。(請注意,第一條中是Select *,第二條是Select 1)

  1. // 沒有效率的: 
  2. $r = mysql_query("SELECT * FROM user WHERE country = 'China'"); 
  3.  if (mysql_num_rows($r) > 0) { 
  4.     // ... 
  5.  } 
  6.  // 有效率的: 
  7. $r = mysql_query("SELECT 1 FROM user WHERE country = 'China' LIMIT 1"); 
  8.  if (mysql_num_rows($r) > 0) { 
  9.     // ... 
  10.  } 

4. 為搜索字段建索引

索引並不一定就是給主鍵或是唯一的字段。如果在你的表中,有某個字段你總要會經常用來做搜索,那麼,請為其建立索引吧。

從上圖你可以看到那個搜索字串 “last_name LIKE ‘a%’”,一個是建了索引,一個是沒有索引,性能差了4倍左右。

另外,你應該也需要知道什麼樣的搜索是不能使用正常的索引的。例如,當你需要在一篇大的文章中搜索一個詞時,如: “WHERE post_content LIKE ‘%apple%’”,索引可能是沒有意義的。你可能需要使用MySQL全文索引 或是自己做一個索引(比如說:搜索關鍵詞或是Tag什麼的)

5. 在Join表的時候使用相當類型的例,並將其索引

如果你的應用程序有很多 JOIN 查詢,你應該確認兩個表中Join的字段是被建過索引的。這樣,MySQL內部會啟動為你優化Join的SQL語句的機制。

而且,這些被用來Join的字段,應該是相同的類型的。例如:如果你要把 DECIMAL 字段和一個 INT 字段Join在一起,MySQL就無法使用它們的索引。對於那些STRING類型,還需要有相同的字符集才行。(兩個表的字符集有可能不一樣)

  1. // 在state中查找company 
  2. $r = mysql_query("SELECT company_name FROM users 
  3.     LEFT JOIN companies ON (users.state = companies.state) 
  4.     WHERE users.id = $user_id"); 
  5.  // 兩個 state 字段應該是被建過索引的,而且應該是相當的類型,相同的字符集。 




  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved