程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MYSQL入門知識 >> MySQL應用優化

MySQL應用優化

編輯:MYSQL入門知識
 

一、基本語句優化原則

(1).盡量避免在索引列上進行運算或函數操作,這樣會導致索引失效

如:

select * from t where Year(d)>=2016;

可以優化為:

select * from t where d>='2016-01-01';

(2).使用join語句時,應用小結果集驅動大結果集。因為在join多表時,可能會導致更多的鎖定和擁塞

(3).注意模糊查詢時避免%%,%開頭的查詢條件會使索引失效

(4).僅列出需要查詢的字段,這對效率沒有影響,但會影響內存

如:

select * from t;

可以優化為:

select name from t;

(5).使用批量交互插入語句以節省交互
如:

insert into t(id,name) values(1,"a");

insert into t(id,name) values(2,"b"); 

可以優化為:

insert into t(id,name) values(1,"a"),(2,"b");

 

這裡也有博友質疑,貼結果:

(6).limit的基數比較大時使用between

如:

select * from article order by id limit 100000,10;

可以優化為:

select * from article between 100000 and 100010 order by id;

這裡需要注意的是,如果id不連續的話,使用between獲得的數據量會少於預計的數據量。

(7).避免使用NULL,這樣會使mysql先進行一次是否為NULL的判定

(8).(這裡頗有爭議,我自己測試並查閱一下資料修改如下。)

如果id作為非主鍵字段,不要使用count(id),而是count(*),因為id未作非空約束時,會先進行NULL值判定

id作為主鍵時,在效率上,count(id)>count(*),若id作為自增主鍵,count(id)的效率會更高

(9).不要做不必要的排序,盡量在索引中進行排序

二、Mysql的存儲引擎分析

  MyISAM Memory InnoDB 用途 快讀 內存數據 完整的事務支持 鎖 全表鎖定 全表鎖定 多重隔離級別的行鎖 持久性 基於表恢復 無磁盤I/O,無可持久性 基於日志的恢復 事務特性 不支持 不支持 支持 支持索引類型 B-tree/FullText/R-tree Hash/B-tree Hash/B-tree

在介紹存儲引擎的選擇原則之前,先介紹一下讀寫比。讀寫比,即讀取和寫入語句執行次數的比,一般理想的讀寫比在100:1左右。

當讀寫比達到10:1的時候,即認為其是以寫為主的數據庫。

(1).采用MyISAM引擎(關鍵是快讀,最簡版的MySQL數據庫)

R/W>100:1,且update較少

並發不高,不需要事務

表數據量小,硬件資源差

(2).采用InnoDB引擎(功能完備的MySQL數據庫)

R/W比較小,數據更新頻繁

海量數據,高並發

安全性、可用性高

(3).采用Memory引擎

內存充足

對數據一致性要求不高

定期歸檔(將過時的歷史數據存入文件系統)

最常用的兩種引擎是MyISAM和InnoDB,MyISAM注重效率,InnoDB注重事務。

三、數據庫設計

1、范式與反范式

在數據庫理論發展的過程中,逐漸形成五大范式,從第一范式到第五范式,數據庫冗余降低,但查詢效率也會隨之降低。

上世紀硬件設備並不發達,空間成本比較高,所以設計理念是提高范式等級,減少冗余,利用時間換取空間,平衡點基本落在第三范式上。那什麼又是反范式呢?隨著硬件設備的發展,空間成本大幅度降低,而更多的是對時間和效率的要求,所以范式等級可以適當降低,增加冗余,最低可把范式降到第一范式。

反范式示例,由於一條記錄被分到多張表中進行記錄,查詢需要進行多表關聯,當要查詢的數據量很大時,連表查詢的時間成本就會很高,更嚴重的情況會引起數據庫服務器宕機。這時候就需要建立冗余表將數據集中到一個表中記錄。冗余表一般符合低等級范式。如何減少冗余表的空間成本呢?一般是定期轉儲。將一段時間之前的數據從數據庫服務器導出,存儲到其他地方,這些數據應是現在無需使用的數據。

2.數據庫分區

講一個數據表的文件和索引分散存儲在不同的物理文件中,這樣在查找的時候就不需要在整個大文件中搜索,而在固定范圍中查找。

假設要存儲某一地區1900-2000年之間出生的孩子信息,按年份分區,代碼如下:

create table child (

id int AUTO_INCREMENT,

name varchar(12) not null,

birth date not null,
primary key(id,birth)
) engine=innoDB partition by range (year(birth))

(partition foo01 values less than(1991), partition foo02 values less than(1992),

partition foo03 values less than(1993), partition foo04 values less than(1994),

partition foo05 values less than(1995), partition foo06 values less than(1996),

partition foo07 values less than(1997), partition foo08 values less than(1998),

partition foo09 values less than(1999), partition foo10 values less than(2000));

3.數據庫分表

分表原理和分區類似,只不過分區是在不同文件中存儲數據,而分表是將一張數據庫表拆分成多張數據庫表。

如:

create table child (

id int primary key AUTO_INCREMENT,

name varchar(12) not null,

birth date not null) engine=innoDB;

可分為:

create table child_xxxx(

id int primary key AUTO_INCREMENT,

name varchar(12) not null,

birth date not null) engine=innoDB;

child_xxxx代表出生年份,如child_1900保存1900年出生的孩子信息,child_1901保存1901年出生的孩子信息,以此類推。

總之,數據庫應用設計還得根據具體的環境來選擇適當的方案。空間和時間的平衡,根據需要具體情況來把握。

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