資料庫效能優化
Mysql效能優化
設計表
-
選取合適的欄位屬性
-
將表中欄位寬度設的儘可能小一些。
例如,可以設成CHAR(6)完成任務,就不要設成CHAR(255)
- 儘量把欄位設定為NOTNULL,這樣資料庫執行的時候就不用去比較null值。
- 對於有些欄位例如“省份”,“性別”,可以設為ENUM型別,ENUM型別被當作數值處理,處理起來速度比文字快。
- 使用外來鍵
- 使用索引,索引應建立在那些將用於JOIN,WHERE判斷和ORDERBY排序的欄位上。儘量不要對資料庫中某個含有大量重複的值的欄位建立索引。 索引最好在相同型別的欄位間進行比較的操作,在建有索引的欄位上儘量不要使用函式。
- 儘可能的使用 varchar/nvarchar 代替 char/nchar
- 儘量使用數字型欄位,若只含數值資訊的欄位儘量不要設計為字元型
- 儘量避免使用遊標,因為遊標的效率較差 ,如果遊標操作的資料超過1萬行,那麼就應該考慮改寫。
SQL語句
-
使用內連線(join)代替子查詢
原因是用連線時,MYSQL不需要在記憶體中建立臨時表來完成邏輯上需要兩個步驟的查詢工作。
-
使用聯合(UNION)來代替手動建立的臨時表
-
使用事務,可以保持資料庫中資料的一致性和完整性。
-
可以通過鎖定表來獲得更好的效能。
LOCK TABLE inventory WRITE SELECT Quantity FROM inventory WHERE Item='book';
UPDATE inventory SET Quantity=11 WHERE Item='book'; UNLOCK TABLES
-
對查詢進行優化,要儘量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。
-
應儘量避免在 where 子句中對欄位進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如:
select id from t where num = 0
-
不使用NOT IN和<>操作
-
不要在列上進行運算
select * from users where YEAR(adddate)<2007; 將在每個行上進行運算,這 將導致索引失效而進行全表掃描,因此我們可以改成 select * from users where adddate<‘2007-01-01';
-
儘量不要用like操作,like"%aaa%"不會使用索引,like"aaa%"可以使用索引。
-
應儘量避免在 where 子句中使用 or 來連線條件
-
select count(*) from table;這樣不帶任何條件的count會引起全表掃描
-
任何地方都不要使用 select * from t ,用具體的欄位列表代替
-
用IN代替OR
-
讀取適當的記錄LIMIT M,N
select id,name from table_name limit 866613, 20 ---> select id,name from table_name where id> 866612 limit 20
-
避免隨機取記錄
select * from t1 where 1=1 order by RAND() LIMIT 4 ---> select * from t1 where id >=CEIL(RAND()*1000) LIMIT 4
-
批量INSERT插入
insert into t (id,name) values(1,'bea') insert into t (id,name) values(2,'bela') insert into t (id,name) values(3,'tom') -----> insert into t(id,name)values(1,'bea'),(2,'bela'),(3,'tom')
-
不要使用NOT等負向查詢條件
索引
-
建立索引
-
複合索引
-
索引不包含有null值的列
-
使用短索引,不僅可以提高查詢速度而且可以節省磁碟空間和I/O操作。
-
資料庫預設排序可以符合要求的情況下不要使用排序操作 ,儘量不要包含多個列的排序,如果需要最好給這些列建立複合索引。
-
索引並不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因為 insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有 必要。
-
儲存引擎不能使用索引中範圍條件右邊的列
如這樣的sql: select * from user where username='123' and age>20 and phone='1390012345',其中username, age, phone都有索引,只有username和age會生效,phone的索引沒有用到。