MySQL 時(shí)間類型 datetime、bigint、timestamp,選哪個(gè)?
在下方公眾號(hào)后臺(tái)回復(fù):面試手冊(cè),可獲取杰哥匯總的 3 份面試 PDF 手冊(cè)。
數(shù)據(jù)庫(kù)中可以用datetime、bigint、timestamp來(lái)表示時(shí)間,那么選擇什么類型來(lái)存儲(chǔ)時(shí)間比較合適呢?
前期數(shù)據(jù)準(zhǔn)備
通過(guò)程序往數(shù)據(jù)庫(kù)插入50w數(shù)據(jù)
數(shù)據(jù)表:
CREATE?TABLE?`users`?(
??`id`?int(11)?NOT?NULL?AUTO_INCREMENT,
??`time_date`?datetime?NOT?NULL,
??`time_timestamp`?timestamp?NOT?NULL?DEFAULT?CURRENT_TIMESTAMP?ON?UPDATE?CURRENT_TIMESTAMP,
??`time_long`?bigint(20)?NOT?NULL,
??PRIMARY?KEY?(`id`),
??KEY?`time_long`?(`time_long`),
??KEY?`time_timestamp`?(`time_timestamp`),
??KEY?`time_date`?(`time_date`)
)?ENGINE=InnoDB?AUTO_INCREMENT=500003?DEFAULT?CHARSET=latin1
其中time_long、time_timestamp、time_date為同一時(shí)間的不同存儲(chǔ)格式
實(shí)體類users
/**
?*?@author?hetiantian
?*?@date?2018/10/21
?*?*/
@Builder
@Data
public?class?Users?{
????/**
?????*?自增唯一id
?????*?*/
????private?Long?id;
????/**
?????*?date類型的時(shí)間
?????*?*/
????private?Date?timeDate;
????/**
?????*?timestamp類型的時(shí)間
?????*?*/
????private?Timestamp?timeTimestamp;
????/**
?????*?long類型的時(shí)間
?????*?*/
????private?long?timeLong;
}
dao層接口
/**
?*?@author?hetiantian
?*?@date?2018/10/21
?*?*/
@Mapper
public?interface?UsersMapper?{
????@Insert("insert?into?users(time_date,?time_timestamp,?time_long)?value(#{timeDate},?#{timeTimestamp},?#{timeLong})")
????@Options(useGeneratedKeys?=?true,keyProperty?=?"id",keyColumn?=?"id")
????int?saveUsers(Users?users);
}
測(cè)試類往數(shù)據(jù)庫(kù)插入數(shù)據(jù)
public?class?UsersMapperTest?extends?BaseTest?{
????@Resource
????private?UsersMapper?usersMapper;
????@Test
????public?void?test()?{
????????for?(int?i?=?0;?i?500000;?i++)?{
????????????long?time?=?System.currentTimeMillis();
????????????usersMapper.saveUsers(Users.builder().timeDate(new?Date(time)).timeLong(time).timeTimestamp(new?Timestamp(time)).build());
????????}
????}
}
sql查詢速率測(cè)試
通過(guò)datetime類型查詢:
select?count(*)?from?users?where?time_date?>="2018-10-21?23:32:44"?and?time_date?<="2018-10-21?23:41:22"
耗時(shí):0.171
通過(guò)timestamp類型查詢
select?count(*)?from?users?where?time_timestamp?>=?"2018-10-21?23:32:44"?and?time_timestamp?<="2018-10-21?23:41:22"
耗時(shí):0.351
通過(guò)bigint類型查詢
select?count(*)?from?users?where?time_long?>=1540135964091?and?time_long?<=1540136482372
耗時(shí):0.130s
結(jié)論 在InnoDB存儲(chǔ)引擎下,通過(guò)時(shí)間范圍查找,性能bigint > datetime > timestamp
sql分組速率測(cè)試
使用bigint 進(jìn)行分組會(huì)每條數(shù)據(jù)進(jìn)行一個(gè)分組,如果將bigint做一個(gè)轉(zhuǎn)化在去分組就沒(méi)有比較的意義了,轉(zhuǎn)化也是需要時(shí)間的
通過(guò)datetime類型分組:
select?time_date,?count(*)?from?users?group?by?time_date
耗時(shí):0.176s
通過(guò)timestamp類型分組:
select?time_timestamp,?count(*)?from?users?group?by?time_timestamp
耗時(shí):0.173s
結(jié)論 在InnoDB存儲(chǔ)引擎下,通過(guò)時(shí)間分組,性能timestamp > datetime,但是相差不大
sql排序速率測(cè)試
通過(guò)datetime類型排序:
select?*?from?users?order?by?time_date
耗時(shí):1.038s
通過(guò)timestamp類型排序
select?*?from?users?order?by?time_timestamp
耗時(shí):0.933s
通過(guò)bigint類型排序
select?*?from?users?order?by?time_long
耗時(shí):0.775s
結(jié)論 在InnoDB存儲(chǔ)引擎下,通過(guò)時(shí)間排序,性能bigint > timestamp > datetime
小結(jié)
如果需要對(duì)時(shí)間字段進(jìn)行操作(如通過(guò)時(shí)間范圍查找或者排序等),推薦使用bigint,如果時(shí)間字段不需要進(jìn)行任何操作,推薦使用timestamp,使用4個(gè)字節(jié)保存比較節(jié)省空間,但是只能記錄到2038年記錄的時(shí)間有限。
來(lái)源:juejin.im/post/6844903701094596615
推薦閱讀
MySQL 大批量插入,如何過(guò)濾掉重復(fù)數(shù)據(jù)?
MySQL 主從復(fù)制解決了什么問(wèn)題?出現(xiàn)同步延遲如何解決?
MySQL 定時(shí)備份數(shù)據(jù)庫(kù)(非常全)
DBA整理的萬(wàn)字詳解MySQL性能優(yōu)化,值得收藏!

