mysql單表最大記錄數
其實mysql本身並沒有對單表最大記錄數進行限制,但是從性能考慮,肯定是有影響的。
曾廣爲流傳的一個說法:mysql單表數據量超過2000萬行,性能會明顯下降,當年的百度DBA測試mysql性能時發現,當單表數據量在2000萬行量級的時候,SQL操作性能急劇下降,因此結論由此而來。
阿里巴巴《java開發手冊》提出單錶行數超過500萬行或者單表容量超過2GB,才推薦進行分庫分表。
事實上,這個數值和實際記錄的條數無關,而與mysql的配置以及機器的硬件有關,mysql爲了提高性能,會將表的索引裝載到內存中,InnoDB buffer size 足夠的情況下,其能完成全加載進內存,查詢不會有問題。但是當單表數據達到某個量級的時候,導致內存無法存儲其索引,使得之後的SQL查詢會產生磁盤IO,從而導致性能下降。當然,這個還和具體的表結構設計有關,最終導致的問題都是內存限制。
mysql配置優化
- innodb_buffer_pool_size = 500M
太小,嚴重影響數據庫性能,服務器共500G內存,但只給mysql緩衝池分配了500M,建議設置爲服務器內存的60%。 - expire_logs_days = 7
太短,只能保留7天的binlog,只能恢復7天內的數據。建議設置爲參數文件裏被覆蓋的90天的設置。 - long_query_time = 10
太長,建議設置爲2秒,讓慢查詢日誌記錄更多的慢查詢。 - transaction-isolation = read-committed
建議註釋掉,使用數據庫默認的事務隔離基本。 - innodb_lock_wait_timeout = 5
設置的太小,會導致事務因鎖等待超過5秒,就被回滾。建議和雲門戶設置保持一致,雲門戶大小爲120. - autocommit = 0
建議改爲mysql默認的自動提交(autocommit=1),提升性能。
數據庫表設計優化
- 表字段避免null值出現,null值很難查詢優化且佔用額外的索引空間,推薦使用默認值代替。
- 儘量使用INT而非BIGINT,如果非負則加上UNSIGNED(這樣數值容量會擴大一倍),當然能使用TINYINT,SMALLINT,MEDIUMIN更好。
- 使用枚舉或整型代替字符串類型。
- 儘量使用TIMESTAMP而非DATETIME。
- 單表不要有太多字段。
- 用整型來存IP。
SQL優化
- 開啓慢查詢日誌來找出慢的sql。
- 使用limit對查詢結果的記錄進行限定。
- 避免使用select * ,將需要查找的字段列出來。
- 使用join代替子查詢。
- or改寫成in:or的效率是n級別,in的效率是log(n)級別,in的個數建議200以內。
- 避免where子句中使用!=或<>,否則引擎將放棄索引而進行全表掃描。
- 列表數據不要拿全表,使用limit進行分頁。