前言html
數據庫是java開發過程必不可少的數據存儲工具,一般咱們分爲關係型數據庫和非關係型數據庫,上一篇中已經簡單的介紹了redis,這裏說一說關係型數據庫mysql。java
一、mysql引擎mysql
這裏只說咱們常見的兩種引擎,MyISAM和Innodb,其餘相關的引擎有興趣的能夠自行了解。首先咱們簡單的說說這兩種引擎的區別。redis
1)MyISAM,不支持事務,支持全文索引、表鎖,在磁盤上有三個與表名相同的文件,.FRM文件存儲表結構,.MYD文件存儲表數據,.MYI文件存儲表索引,MyISAM不緩存數據,只緩存索引。算法
2)InnoDB,支持事務、外鍵、行鎖和非鎖定讀,即默認狀況下讀不產生鎖。InnoDB由一系列後臺線程和一大塊內存組成。默認狀況下,後臺線程有7個,4個IO線程,1個master thread,1個lock監控線程,1個error監控線程。sql
在實際開發中,因爲事務和行級鎖等機制的緣由,Innodb可能接觸的更多一些。MyISAM更多用於查詢,尤爲是select * from tableName,能夠直接獲取到數值,不須要全表掃描。數據庫
二、mysql結構編程
mysql的結構以下圖所示,我的十分喜歡這張圖,經過這張圖還能夠大體瞭解一條SQL語句的執行過程後端
select * from tableName where name like '_zhang' select * from tableName where name like '%zhang'
上述兩個sql沒法使用name列上的索引緩存
select * from tableName where name like 'zhang_' select * from tableName where name like 'zhang%'
上述兩個sql可使用name列上的索引
還有一點須要注意的是,對於變化較少的字段不建議添加索引,如性別的列,一般的值是0和1或者true和false,此列添加索引不會有太大的速度提高。一個表的索引個數也不建議過多,增刪改數據的同時還要維護索引,過多的索引會下降數據庫的效率。
四、mysql優化
mysql的優化從三個方面入手,包括建立表時的優化,索引的建立以及sql的優化
1)建立表時的優化
a)爲表添加主鍵ID,最好使用無符號的int類型,設置成自增(注意分表時id重複的狀況)
b)針對字典表能夠考慮使用ENUM類型代替字符串,若是插入的值不在ENUM規定值內,則自動使用''空字符串代替
c)儘可能使用NOT NULL,使用NULL須要額外的空間,並且NULL沒法使用索引
d)使用PROCEDURE ANALYSE()函數取得建議,根據表中數據進行分析,因此須要數據庫中有必定的數據作基礎,如:
SELECT * FROM sys_user PROCEDURE ANALYSE();
越小的列越快,在考慮往後數據擴展的前提下,儘可能使用較小存儲單元的類型,如字典表中數據較少時,主鍵能夠放棄使用INT,用MEDIUMINT、SMALLINT來代替,甚至使用更小的TINYINT,若是不須要記錄時間,可使用DATE代替DATETIME
e)使用固定長度的表,若是表中全部的列都是固定長度的,表會被認爲是「static」的,會加快查詢速度,若是列中包含varchar、text或blog之一,則表不是固定長度的。固定長度的表因爲定長,能夠根據偏移量計算下一條數據的位置,而變長的表只能經過尋找下一條數據的主鍵。固定長度的表的缺點就是會形成空間浪費,由於不管存儲數據大小,都會分配定長的空間。注:mysql字段佔用空間與類型有關,如int(11)和int(3)都佔用四個字節的長度,區別是根據存儲數據的長度自動補全零位的個數,存儲1111時,因爲長度是4,int(3)不須要補零,int(11)會自動補全7個0
f)表分割,表分割能夠分爲水平分割和垂直分割。水平分割就是創建結構相同可是表名不一樣的表,將數據按照hash運算以後存儲在對應的表中,如sys_user_1,sys_user_2等;垂直分割是將表中一些不經常使用的或者會常常更新致使查詢緩存失效的列分割出來,如家庭住址,最後登陸時間等字段。注:被分割的字段不能常常被JOIN,不然會極大下降性能
g)數據庫讀寫分離
2)索引的建立
索引的建立就是在適合的列上添加索引,從而達到加快查詢速度的效果,上面已經說起,這裏再也不累述。
3)SQL的優化
a)使用explain關鍵字解析sql語句,如:
EXPLAIN SELECT * FROM (SELECT user_sex,COUNT(*) AS counts FROM sys_user u GROUP BY u.user_sex) count_t WHERE count_t.counts > 1
結果以下所示:
一般咱們關注的是type這一列,這裏不要求記住全部,只須要記住幾個典型的,而且瞭解哪一個更優便可,如system、const、eq_ref、ref、range、index、all等。這裏有一篇文章,你們能夠參考瞭解一下:《mysql explain 的type解釋》
b)在查詢結果明確只有一條的狀況下,且該列上沒有索引,使用LIMIT 1能夠在查詢到數據以後直接返回,避免全表掃描;判斷一條數據是否存在時,使用SELECT 1能夠提升查詢速度,SELECT 1 > SELECT any column > SELECT *
c)避免SELECT *,用什麼數據取什麼列,減小網絡數據傳輸
d)儘可能少用having、in、not in、is null等關鍵字或判斷,對於having,可使用子查詢來代替;in和not in可使用exists和not exists代替,若是數據連續,也可使用between and代替。
五、Innodb文件結構
InnoDB表由共享表空間或獨立表空間、日誌文件組和表結構文件組成。可使用show variables like 'innodb_file_per_table'查看是否開啓了獨立表空間,結果爲ON時表示開啓獨立表空間;OFF時表示使用共享共享表空間。
select * from tableName where id =1 lock in share mode
select * from tableName where id =1 for update
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。
原文連接:http://www.cnblogs.com/1ning/p/6705129.html