MySQL數據庫十年夜優化技能。本站提示廣大學習愛好者:(MySQL數據庫十年夜優化技能)文章只能為提供參考,不一定能成為您想要的結果。以下是MySQL數據庫十年夜優化技能正文
2.用EXPLAIN使你的SELECT查詢加倍清楚
應用EXPLAIN症結字是另外一個MySQL優化技能,可讓你懂得MySQL正在停止甚麼樣的查詢操作,這可以贊助你發明瓶頸的地點,並顯示出查詢或表構造在哪裡出了成績。
EXPLAIN查詢的成果,可以告知你那些索引正在被援用,表是若何被掃描和排序的等等。
完成一個SELECT查詢(最好是比擬龐雜的一個,帶joins方法的),在外面添加上你的症結詞說明,在這裡我們可使用phpMyAdmin,他會告知你表中的成果。舉例來講,假設當我在履行joins時,正忘卻往一個索引中添加列,EXPLAIN能贊助我找到成績的地點。
添加索引到group_id field後
3.應用LIMIT 1獲得獨一行
有時,當你要查詢一張表是,你曉得本身只須要看一行。你能夠會去的一條非常奇特的記載,或許只是恰好檢討了任何存在的記載數,他們都知足了你的WHERE子句。
在這類情形下,增長一個LIMIT 1會令你的查詢加倍有用。如許數據庫引擎發明只要1後將停滯掃描,而不是去掃描全部表或索引。
// do I have any users from Alabama?
// what NOT to do:
$r = mysql_query("SELECT * FROM user WHERE state = 'Alabama'");
if (mysql_num_rows($r) > 0) {
// ...
}
// much better:
$r = mysql_query("SELECT 1 FROM user WHERE state = 'Alabama' LIMIT 1");
if (mysql_num_rows($r) > 0) {
// ...
}
4. 索引中的檢索字段
索引不只是主鍵或獨一鍵。假如你想搜刮表中的任何列,你應當一向指向索引。
5.包管銜接的索引是雷同的類型
假如運用法式中包括多個銜接查詢,你須要確保你鏈接的列在雙方的表上都被索引。這會影響MySQL若何優化外部聯接操作。
另外,參加的列,必需是統一類型。例如,你參加一個DECIMAL列,而同時參加另外一個表中的int列,MySQL將沒法應用個中至多一個目標。即便字符編碼必需同為字符串類型。
// looking for companies in my state
$r = mysql_query("SELECT company_name FROM users
LEFT JOIN companies ON (users.state = companies.state)
WHERE users.id = $user_id");
// both state columns should be indexed
// and they both should be the same type and character encoding
// or MySQL might do full table scans
6.不要應用BY RAND()敕令
這是一個令許多老手法式員會失落出來的圈套。你能夠不知不覺中制作了一個恐怖的鎮靜。這個圈套在你是用BY RAND()敕令時就開端創立了。
假如您真的須要隨機顯示你的成果,有許多更好的門路去完成。固然這須要寫更多的代碼,然則能防止機能瓶頸的湧現。成績在於,MySQL能夠會為表中每個自力的行履行BY RAND()敕令(這會消費處置器的處置才能),然後給你僅僅前往一行。
// what NOT to do:
$r = mysql_query("SELECT username FROM user ORDER BY RAND() LIMIT 1");
// much better:
$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");
7.盡可能防止SELECT *敕令
從表中讀取越多的數據,查詢會變得更慢。他增長了磁盤須要操作的時光,照樣在數據庫辦事器與WEB辦事器是自力離開的情形下。你將會閱歷異常漫長的收集延遲,僅僅是由於數據不用要的在辦事器之間傳輸。
一直指定你須要的列,這是一個異常優越的習氣。
// not preferred
$r = mysql_query("SELECT * FROM user WHERE user_id = 1");
$d = mysql_fetch_assoc($r);
echo "Welcome {$d['username']}";
// better:
$r = mysql_query("SELECT username FROM user WHERE user_id = 1");
$d = mysql_fetch_assoc($r);
echo "Welcome {$d['username']}";
// the differences are more significant with bigger result sets
8.從PROCEDURE ANALYSE()中取得建議
PROCEDURE ANALYSE()可以讓MySQL的柱構造剖析和表中的現實數據來給你一些建議。假如你的表中曾經存在現實數據了,能為你的嚴重決議計劃辦事。
9.預備好的語句
預備好的語句,可以從機能優化和平安兩方面臨年夜家有所贊助。
預備好的語句在過濾曾經綁定的變量默許情形下,能給運用法式以有用的掩護,避免SQL注入進擊。固然你也能夠手動過濾,不外因為年夜多半法式員忘記的性情,很難到達後果。
// create a prepared statement
if ($stmt = $mysqli->prepare("SELECT username FROM user WHERE state=?")) {
// bind parameters
$stmt->bind_param("s", $state);
// execute
$stmt->execute();
// bind result variables
$stmt->bind_result($username);
// fetch value
$stmt->fetch();
printf("%s is from %s\n", $username, $state);
$stmt->close();
}
10.將IP地址存儲為無符號整型
很多法式員在創立一個VARCHAR(15)時並沒無意識到他們可以將IP地址以整數情勢來存儲。當你有一個INT類型時,你只占用4個字節的空間,這是一個固定年夜小的范疇。
你必需肯定你所操作的列是一個UNSIGNED INT類型的,由於IP地址將應用32位unsigned integer。
$r = "UPDATE users SET ip = INET_ATON('{$_SERVER['REMOTE_ADDR']}') WHERE user_id = $user_id";
十年夜MySQL優化技能就引見到這裡。