簡單的資料庫優化
不管用什麼樣的語言,資料庫是必不可少的,因此資料庫優化是必備的。
下面列舉幾條基本的簡單的資料庫優化,環境是php + mysql。
1.合理設定欄位屬性。
大家都知道資料庫中的表越小,在它上面執行的查詢也就會越快。因此合理設定欄位屬性,使資料庫表儘可能小點,是最簡單的資料庫優化了。
(1)越小的資料型別通常更好:越小的資料型別通常在磁碟、記憶體和CPU快取中都需要更少的空間,處理起來更快。
(2)簡單的資料型別更好:整型資料比起字元,處理開銷更小,因為字串的比較更復雜。在MySQL中,應該用內建的日期和時間資料型別,而不是用字串來儲存時間;以及用整型資料型別儲存IP地址。
(3)儘量避免NULL:應該指定列為NOT NULL,除非你想儲存NULL。在MySQL中,含有空值的列很難進行查詢優化,因為它們使得索引、索引的統計資訊以及比較運算更加複雜。你應該用0、一個特殊的值或者一個空串代替空值。
2.使用連線(JOIN)來代替子查詢
往往效能這玩意兒,更多時候體現在資料量比較大的時候,此時,我們應該避免複雜的子查詢。如下:
子查詢
insert into t1(a1) select b1 from t2 where not exists(select 1 from t1 where t1.id = t2.r_id);
JOIN
insert into t1(a1) select b1 from t2 left join (select distinct t1.id from t1 ) t1 on t1.id = t2.r_id where t1.id is null;
3,事務
儘管sql語句越少,執行速度越快,但是有些時候,並不是一跳sql語句可以搞定的。比如說,某商城網站付款完成要先扣餘額,然後訂單狀態成功,但是如果扣完錢了,資料庫突然崩潰,訂單狀態沒改,這就會出現很嚴重的問題。
下面介紹一下thinkphp的事務。
$order = M(‘order’); $allAdded = true; //先設定一個值為 true; $data['name'] = 'winter'; $order->startTrans(); //開啟事物 for($i = 1;$i<3;$i++){ $sign = $order->add($data); //新增一條資料到order表 if(!$sign){ $order->rollback(); //如果order新增失敗事物回滾 $allAdded = false; //並且把allAdded設定為 false } } //回滾 if($allAdded){ $order->commit(); // 如果allAdded為真則兩條資料都成功;那麼 commit事物提交 echo '新增成功'; }else{ echo '新增失敗'; }
如果commit了。那麼就提交插入資料。如果發現alladded為假說明有條資料沒插入正確。那麼就rollback回滾就會取消事物開啟之後操作資料庫的所有行為。
4. 合理使用索引
索引對查詢的速度有著至關重要的影響,理解索引也是進行資料庫效能調優的起點。
索引是儲存引擎用於快速查詢記錄的一種資料結構,通過合理的使用資料庫索引可以大大提高系統的訪問效能,接下來主要介紹在MySql資料庫中索引型別,以及如何創建出更加合理且高效的索引技巧。
Mysql常見索引有:主鍵索引、唯一索引、普通索引、全文索引、組合索引
PRIMARY KEY(主鍵索引) ALTER TABLE `table_name` ADD PRIMARY KEY ( `col` )
UNIQUE(唯一索引) ALTER TABLE `table_name` ADD UNIQUE (`col`)
INDEX(普通索引) ALTER TABLE `table_name` ADD INDEX index_name (`col`)
FULLTEXT(全文索引) ALTER TABLE `table_name` ADD FULLTEXT ( `col` )
組合索引 ALTER TABLE `table_name` ADD INDEX index_name (`col1`, `col2`, `col3` )
5.優化的查詢語句
絕大多數情況下,使用索引可以提高查詢的速度,但如果SQL語句使用不恰當的話,索引將無法發揮它應有的作用。下面是應該注意的幾個方面。首先,最好是 在相同型別的欄位間進行比較的操作。在MySQL 3.23版之前,這甚至是一個必須的條件。例如不能將一個建有索引的INT欄位和BIGINT欄位進行比較;但是作為特殊的情況,在CHAR型別的欄位和 VARCHAR型別欄位的欄位大小相同的時候,可以將它們進行比較。其次,在建有索引的欄位上儘量不要使用函式進行操作。
例如,在一個DATE型別的欄位上使用YEAE()函式時,將會使索引不能發揮應有的作用。所以,下面的兩個查詢雖然返回的結果一樣,但後者要比前者快得多。
1 2 |
|
同樣的情形也會發生在對數值型欄位進行計算的時候:
1 2 |
|
上面的兩個查詢也是返回相同的結果,但後面的查詢將比前面的一個快很多。第三,在搜尋字元型欄位時,我們有時會使用 LIKE 關鍵字和萬用字元,這種做法雖然簡單,但卻也是以犧牲系統性能為代價的。例如下面的查詢將會比較表中的每一條記錄。
1 2 |
|
但是如果換用下面的查詢,返回的結果一樣,但速度就要快上很多:
1 2 |
|
最後,應該注意避免在查詢中讓MySQL進行自動型別轉換,因為轉換過程也會使索引變得不起作用。