1. 程式人生 > >簡單的資料庫優化

簡單的資料庫優化

 

 

不管用什麼樣的語言,資料庫是必不可少的,因此資料庫優化是必備的。

下面列舉幾條基本的簡單的資料庫優化,環境是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

SELECT FROM order WHERE YEAR(OrderDate)<2001;

SELECT FROM order WHERE OrderDate<"2001-01-01";

同樣的情形也會發生在對數值型欄位進行計算的時候:

1

2

SELECT FROM inventory WHERE Amount/7<24;

SELECT FROM inventory WHERE Amount<24*7;

上面的兩個查詢也是返回相同的結果,但後面的查詢將比前面的一個快很多。第三,在搜尋字元型欄位時,我們有時會使用 LIKE 關鍵字和萬用字元,這種做法雖然簡單,但卻也是以犧牲系統性能為代價的。例如下面的查詢將會比較表中的每一條記錄。

1

2

SELECT FROM books

WHERE name like "MySQL%"

但是如果換用下面的查詢,返回的結果一樣,但速度就要快上很多:

1

2

SELECT FROM books

WHERE name>="MySQL"and name<"MySQL"

最後,應該注意避免在查詢中讓MySQL進行自動型別轉換,因為轉換過程也會使索引變得不起作用。