這次分享準備的有些倉促,所以都比較零散,有些是針對開發中產生的疑問做分享
一、mysql基礎
1.1 數據庫存儲方式
提出一個疑問:MySQL是如何使用內存和磁盤的?
磁盤空間的占用:
每個數據庫對應MySQL數據目錄下的一個目錄,不管你是采用什么存儲引擎。
每張數據表都在其對應的數據庫目錄下有一個table_name.frm文件,存儲的是表定義信息,有64KB的限制。
MyISAM引擎表在其數據庫目錄下對應3個文件,包括上面的frm文件,還有數據文件和索引文件。
Innodb有自己的表空間和redo日志文件。(不了解,需研究)
MySQL還有自己的日志文件,包括error log, binary log, general log等。
觸發器存儲在對應的數據庫目錄下。
認證信息存儲在MySQL系統表里,在mysql庫下。(不了解)
另外mysqld服務器程序和其他一些客戶端管理工具等也需要占用一定的磁盤空間。
內存的占用:
線程管理,服務器程序為了提高效率,會將一些信息存儲于buffer(cache)。
Memory(HEAP)引擎將數據存儲在內存中。
臨時表如果沒有超過設定的限制會存儲在內存中。
每個客戶端連接都會使用一定的buffer空間
全局的Buffer和Cache(比如MyISAM的keybuffer,InnoDB的buffer pool, Query cache等 )
1.2 內存的分配
提問: cache 和 buffer 有區別嗎?區別是什么?
二、優化手段
2.1 服務器系統優化(不了解)
2.2 mysql配置優化
mysql核心參數 : innodb_buffer_pool_size
2.3 MySQL Schema 優化(沒了解)
2.4 查詢優化
2.4.1 索引建立規則
1、 cardinality
show index from cmf_users
2、 總結: http://blog.csdn.net/xluren/article/details/32746183
1、索引雖然提高了查詢速度,同時卻會降低更新表的速度,因為更新表時,MySQL不僅要保存數據,還要保存一下索引文件。
3、查詢時要匹配類型
http://www.zendstudio.net/archives/single-quotes-or-no-single-quotes-in-sql-query/
4、表join之前先用where過濾數據(性能高)
5、避免 SELECT *
2.4.2 on和where執行順序
三、數據庫字段設計
3.1 寬度的意義
varchar(5)和varchar(200)區別
解釋:
雖然他們用來存儲90個字符的數據,其存儲空間相同。但是對于內存的消耗是不同的。對于VARCHAR數據類型來說,硬盤上的存儲空間雖然都是根據實際字符長度來分配存儲空間的,但是對于內存來說,則不是。其時使用固定大小的內存塊來保存值。簡單的說,就是使用字符類型中定義的長度,即200個字符空間。顯然,這對于排序或者臨時表(這些內容都需要通過內存來實現)作業會產生比較大的不利影響。
所以如果某些字段會涉及到文件排序或者基于磁盤的臨時表時,分配VARCHAR數據類型時仍然不能夠太過于慷慨。還是要評估實際需要的長度,然后選擇一個最長的字段來設置字符長度。如果為了考慮冗余,可以留10%左右的字符長度。
3.2 關于時間字段的設計
參考: http://blog.csdn.net/wuzekai2010/article/details/53149133
四、分享中提出的疑問
4.1 觸發器對性能有損耗嗎?該不該用?
[圖片上傳失敗...(image-50b5c1-1511332008215)]
4.2 mysql/data文件下其他的文件是什么用處?
ibdata1:
當你啟用了 innodb_file_per_table,表被存儲在他們自己的表空間里,但是共享表空間仍然在存儲其它的 InnoDB 內部數據:
數據字典,也就是 InnoDB 表的元數據
變更緩沖區
雙寫緩沖區
撤銷日志
4.3 查詢時用到臨時表為什么性能差?
參考: http://blog.jobbole.com/102040/
MySQL臨時表分為“內存臨時表”和“磁盤臨時表”,其中內存臨時表使用MySQL的MEMORY存儲引擎,磁盤臨時表使用MySQL的MyISAM存儲引擎;一般情況下,MySQL會先創建內存臨時表,但內存臨時表超過配置指定的值后,MySQL會將內存臨時表導出到磁盤臨時表;
4.4 buffer能手動關閉嗎?buffer有類別區分嗎?
4.5 open_file_limit具體意思是什么?
4.6 float和int類型的字段的優缺?