Scheme設計與數據類型優化
選擇數據類型只要遵循小而簡單的原則就好,越小的數據類型一般會更快,佔用更少的磁盤、內存,處理時須要的CPU週期也更少。越簡單的數據類型在計算時須要更少的CPU週期,好比,整型就比字符操做代價低,於是會使用整型來存儲ip地址,使用DATETIME來存儲時間,而不是使用字符串。
這裏總結幾個可能容易理解錯誤的技巧:
- 一般來講把可爲NULL的列改成NOT NULL不會對性能提高有多少幫助,只是若是計劃在列上建立索引,就應該將該列設置爲NOT NULL。
- 對整數類型指定寬度,好比INT(11),沒有任何卵用。INT使用32位(4個字節)存儲空間,那麼它的表示範圍已經肯定,因此INT(1)和INT(20)對於存儲和計算是相同的。
- UNSIGNED表示不容許負值,大體可使正數的上限提升一倍。好比TINYINT存儲範圍是-128 ~ 127,而UNSIGNED TINYINT存儲的範圍倒是0 - 255。
- 一般來說,沒有太大的必要使用DECIMAL數據類型。即便是在須要存儲財務數據時,仍然可使用BIGINT。好比須要精確到萬分之一,那麼能夠將數據乘以一百萬而後使用BIGINT存儲。這樣能夠避免浮點數計算不許確和DECIMAL精確計算代價高的問題。
- TIMESTAMP使用4個字節存儲空間,DATETIME使用8個字節存儲空間。於是,TIMESTAMP只能表示1970 - 2038年,比DATETIME表示的範圍小得多,並且TIMESTAMP的值因時區不一樣而不一樣。
- 大多數狀況下沒有使用枚舉類型的必要,其中一個缺點是枚舉的字符串列表是固定的,添加和刪除字符串(枚舉選項)必須使用ALTER TABLE(若是隻只是在列表末尾追加元素,不須要重建表)。
- schema的列不要太多。緣由是存儲引擎的API工做時須要在服務器層和存儲引擎層之間經過行緩衝格式拷貝數據,而後在服務器層將緩衝內容解碼成各個列,這個轉換過程的代價是很是高的。若是列太多而實際使用的列又不多的話,有可能會致使CPU佔用太高。
- 大表ALTER TABLE很是耗時,MySQL執行大部分修改表結果操做的方法是用新的結構建立一個張空表,從舊錶中查出全部的數據插入新表,而後再刪除舊錶。尤爲當內存不足而表又很大,並且還有很大索引的狀況下,耗時更久。固然有一些奇技淫巧能夠解決這個問題,有興趣可自行查閱。