mysql 優化 (1)
提高IOPS能力的幾種方法
換SSD,PCIE-SSD(提高IO效率,普通SAS盤5000以內的iops,而新設備可達到數萬或者數十萬iops)
少做IO的活(合並多次讀寫為一次,或者前端加內存CACHE;或者優化業務,消除IO)
加大內存(更多hot data和dirty data放在內存中,減少物理IO)
調整文件系統為xfs(相比ext3、ext4提高IOPS能力,高io負載下表現更佳)
調整raid級別為raid 1+0(相比raid1、raid5等提高IOPS能力)
調整寫cache策略為wb或force wb(利用陣列卡cache,提高iops)
io scheduler(優先使用deadline,如果是SSD,則使用noop)
SSD設備相關優化手段:
• 通過調整 /sys/block/sdx/queue/read_ahead_kb 觀察到預讀大小為16KB(具體多少要看平均每次IO讀大小),通過適當預讀提高整體性能。
• 大量的IO請求數必定會產生龐大數量的中斷請求,因此需要在多核上綁定中斷,避免單核負載過高。
vm.swappiness 設置為0表示盡量少swap,100表示盡量將inactive的內存頁交換出去,在內存不夠用時,釋放掉,盡量不使用swap
RHEL 7以下設置為0,RHEL 7以上謹慎設置為5 ~ 10,減少使用swap的概率
[[email protected] ~]# cat /etc/sysctl.conf |grep vm.swappiness
[[email protected] ~]# sysctl -p
mysql 不使用HugePages
### TokuDB need this kernel settings, start
echo never &get; /sys/kernel/mm/redhat_transparent_hugepage/defrag
echo never &get; /sys/kernel/mm/redhat_transparent_hugepage/enabled
echo never &get; /sys/kernel/mm/transparent_hugepage/enabled
### TokuDB need this kernel settings, end
deadline: deadline 算法保證對既定的IO請求以最小的延遲時間。
anticipatory: 有個IO發生後,如果又有進程請求IO,則產生一個默認6ms猜測時間,猜測下一個進程請求IO是幹什麽。這對於隨機讀取會造成較大的延時。對數據庫應用很糟糕,而對於Web Server等則會表現不錯。
cfq: 對每個進程維護一個IO隊列,各個進程發來的IO請求會被cfq以輪循方式處理,對每一個IO請求都是公平。適合離散讀的應用。
noop: 對所有IO請求都用FIFO隊列形式處理。默認IO不會存在性能問題。
首選xfs,其次ext4
mount參數:noatime, nodiratime, nobarrier
對於ext3, ext4和 reiserfs文件系統可以在mount時指定barrier=0;對於xfs可以指定nobarrier選項
query_cache_type = 0
query_cache_size = 0
tmp_table_size / max_heap_table_size 不建議超過128MB,高並發,簡單SQL的場景中,不建議超過64MB
sort_buffer_size / read_buffer_size 等不建議超過8MB
純InnoDB環境下,key_buffer_size 不建議超過32MB
日誌相關
long_query_time = 0.01(10毫秒)
pt-query-digest + Box Anemometer,構建slow query log分析系統
genral_log = 0
log_warnings = 2
binlog = 0/1
sync_binlog = 0/1/N 需要權衡
log_slave_updates = 0/1,在一個集群中,只有一個SLAVE節點開啟,其他SLAVE都不開啟
MySQL Schema設計原則、優化建議;
• 默認InnoDB,杜絕MyISAM
• 不對InnnoDB表進行在線實時統計
• InnoDB表顯式指定自增INT型為主鍵
• 表字段設計:簡單至上
• INT/TIMESTAMP記錄時間,而非DATETIME
• IPV4地址用INT,而不是CHAR(15)
• 性別采用ENUM(1,2,3)或者是 tinyint,而不是INT,甚至CHAR
• 杜絕TEXT、BLOG,確實需要則拆分
• 存儲較長字符串內容時,提前進行(物理、邏輯)壓縮、序列化(JSON/BSON格式)
• 相同用途未來可能會作為JOIN依據的字段,在各個表裏的定義屬性完全一致
• 顯式約束:NOT NULL,DEFAULT ‘‘
CREATE TABLE `sy_hot_words` (
`id` int(11) NOT NULL,
`hot_words` varchar(510) default NULL COMMENT ‘熱詞以逗號隔開‘,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
可以調整為縱向存儲,或使用其他模糊搜索技術實現,
或者拆分開,采用 1對N 的結構實現,或者在nosql裏,用K-V方式存儲
Schema設計、優化,我們可做的:
-- 理解各業務產生的數據流,以及讀寫數據的方式;
-- 整理數據流中的每個數據項屬性信息(類型、範圍、過濾性);
-- 分析業務指標,推測數據規模(需要考慮相對長遠,例如半年以上,也可以生成一定量級的測試數據,例如至少100萬行);
-- 選擇相對最適用的硬件設備和數據庫架構;
-- 權衡各個SQL的性能和IO量,也即類似於哪個操作權重高一些,那些操作權重適當低一些;
-- 創建適當的索引;
-- 收集測試和生產環境的反饋信息,持續優化索引及表設計;
索引使用中的局限性;
- 通過索引掃描的記錄數超過30%,變成全表掃描
- 聯合索引中,第一個索引列使用範圍查詢
- 聯合索引中,第一個查詢條件不是最左索引列
- 模糊查詢條件列最左以通配符 % 開始
- 內存表(HEAP 表)使用HASH索引時,使用範圍檢索或者ORDER BY
- 兩個獨立索引,其中一個用於檢索,一個用於排序
• 主鍵/唯一索性能引優於普通索引
• 復合索引比普通索引更合適
• 過度索引可能會帶來災難,夠用就行
• 基數(cardinality)很小的列上不建索引
• 長字段使用部分索引,而非全部
• 冗余反向字段便於反向檢索
• 采用第三方全文索引工具或者關鍵字(TAG)對TEXT/BLOB/CHAR字段檢索
• 常用檢索、排序字段,需要創建索引
• 常用檢索、分組(GROUP BY)、排序(ORDER BY)字段,需要創建索引
mysql 優化 (1)