原本要找的是 AUTO_INCREMENT 爆掉的問題該怎麼處理
意外找到這個可以提昇資料庫效率的方法~
詳細說明可以直接看下列的參考資料
參考資料:
1、通過分區(Partition)提升MySQL性能(一)
2、通過分區(Partition)提升MySQL性能(二)
3、mysql 的 partition 與 auto_increment
在 [1] 的效能測試中,建了兩個資料表,一個使用 Partition、一個沒使用
然後用隨機產生的資料填入 800 萬筆資料,測試找出時間是 1995 年間的所有資料
在沒有做 Partition 的資料表中花了 38 秒,有做 Partition 的則只花了 3 秒多~
當資料有顯著的分區效果時,做 Partition 可以降低搜尋資料的時間~
不過後來又找到 [3],同時使用 AUTO_INCREMENT 跟 Partition 時 MySQL 可能會有問題....
目前暫定的作法是使用 Partition、放棄 AUTO_INCREMENT
用其他 INDEX 來盡可能達到類似 AUTO_INCREMENT 的 PRIMARY KEY 效果~
附錄1:我用的 SQL statement
CREATE TABLE `house_object` ( `object_timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE = MYISAM PARTITION BY RANGE (year(object_timestamp)) ( PARTITION p1 VALUES LESS THAN( 2012 ) , PARTITION p2 VALUES LESS THAN( 2013 ) , PARTITION p3 VALUES LESS THAN( 2014 ) , PARTITION p4 VALUES LESS THAN( 2015 ) , PARTITION p5 VALUES LESS THAN( 2016 ) , PARTITION p6 VALUES LESS THAN( 2017 ) , PARTITION p7 VALUES LESS THAN( 2018 ) , PARTITION p8 VALUES LESS THAN( 2019 ) , PARTITION p9 VALUES LESS THAN( 2020 ) , PARTITION p10 VALUES LESS THAN( 2021 ) , PARTITION p11 VALUES LESS THAN( 2022 ) , PARTITION p12 VALUES LESS THAN( 2023 ) , PARTITION p13 VALUES LESS THAN( 2024 ) , PARTITION p14 VALUES LESS THAN( 2025 ) , PARTITION p15 VALUES LESS THAN( 2026 ) , PARTITION p16 VALUES LESS THAN( 2027 ) , PARTITION p17 VALUES LESS THAN( 2028 ) , PARTITION p18 VALUES LESS THAN( 2029 ) , PARTITION p19 VALUES LESS THAN( 2030 ) , PARTITION p20 VALUES LESS THAN( 2031 ) , PARTITION p21 VALUES LESS THAN MAXVALUE );
附錄2:在我的實機(ubuntu 11.10)上發現 ubuntu 目前的 MySQL 版本 5.1.61-0ubuntu0.11.10.1 不支援使用 timestamp 來做 Partition,所以必須改成別的方法,我的作法是改用 Java 的 Date.getTime() 取得的數字來做 Partition。
CREATE TABLE IF NOT EXISTS house_object ( PARTITION BY RANGE (object_timestamp) ( object_timestamp INT NOT NULL ) PARTITION BY RANGE (object_timestamp) ( PARTITION partition1 VALUES LESS THAN (1325347200000) ENGINE = MyISAM, PARTITION partition2 VALUES LESS THAN (1356969600000) ENGINE = MyISAM, PARTITION partition3 VALUES LESS THAN (1388505600000) ENGINE = MyISAM, PARTITION partition4 VALUES LESS THAN (1420041600000) ENGINE = MyISAM, PARTITION partition5 VALUES LESS THAN (1451577600000) ENGINE = MyISAM, PARTITION partition6 VALUES LESS THAN (1483200000000) ENGINE = MyISAM, PARTITION partition7 VALUES LESS THAN (1514736000000) ENGINE = MyISAM, PARTITION partition8 VALUES LESS THAN (1546272000000) ENGINE = MyISAM, PARTITION partition9 VALUES LESS THAN (1577808000000) ENGINE = MyISAM, PARTITION partition10 VALUES LESS THAN (1609430400000) ENGINE = MyISAM, PARTITION partition11 VALUES LESS THAN (1640966400000) ENGINE = MyISAM, PARTITION partition12 VALUES LESS THAN (1672502400000) ENGINE = MyISAM, PARTITION partition13 VALUES LESS THAN (1704038400000) ENGINE = MyISAM, PARTITION partition14 VALUES LESS THAN (1735660800000) ENGINE = MyISAM, PARTITION partition15 VALUES LESS THAN (1767196800000) ENGINE = MyISAM, PARTITION partition16 VALUES LESS THAN (1798732800000) ENGINE = MyISAM, PARTITION partition17 VALUES LESS THAN (1830268800000) ENGINE = MyISAM, PARTITION partition18 VALUES LESS THAN (1861891200000) ENGINE = MyISAM, PARTITION partition19 VALUES LESS THAN (1893427200000) ENGINE = MyISAM, PARTITION partition20 VALUES LESS THAN (1924963200000) ENGINE = MyISAM, PARTITION partition21 VALUES LESS THAN MAXVALUE ENGINE = MyISAM );
這樣的效果跟前面是一樣的,以一年做分區,不過每次 INSERT 時都要自己指定 object_timstamp 的值。
沒有留言:
張貼留言