我們目前正在評估MySQL分區對於我們的小應用程序的使用。應用程序基本上只是坐在消息隊列的末尾,並使用Hibernate將我們的API請求(包括時間戳)記錄到數據庫中。不幸的是,我們收到很多請求,查詢數據庫變得非常緩慢。用Hibernate管理MySQL分區
我們想要做的是按時間戳(每月)對錶格進行分區,因爲我們的常規查詢模式類似於「在時間A和B之間獲得某些請求」。如果A和B連續兩個月,這將主要是真實的,那麼這將只是兩個分區。
由於MySQL的範圍分區必須手動創建,所以我想將這個維護任務添加到我們的Java應用程序中,它可以自動完成。我們的想法是這樣的:
- 有定期執行的程序線程(使用
ScheduledExecutorService
或東西) - 在線程,檢查是否有下個月
- 如果不分區,創建
這一切都很好,但我堅持嘗試使用Hibernate獲取MySQL的分區信息並創建分區。什麼是最好的方式來做到這一點(我確定,如果這將是特定於MySQL)?
- 在Hibernate中是否有一個特定的API來獲取表的MySQL分區信息,還可以創建分區?
- 我應該使用原始SQL(
SHOW CREATE TABLE ...
,ALTER TABLE ... ADD PARTITION
)並自己解析輸出嗎?
編輯:
表看起來像這樣(我刪除了一些的問題不相關列):
CREATE TABLE `request` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`apikey` varchar(32) NOT NULL,
`timestamp` datetime NOT NULL,
`rows` int(11) DEFAULT NULL,
`user_id` varchar(15) DEFAULT NULL
PRIMARY KEY (`id`),
KEY `apikey_idx` (`apikey`),
KEY `timestamp_idx` (`timestamp`),
KEY `apikey_timestamp_rows_idx` (`apikey`,`timestamp`,`rows`)
) ENGINE=InnoDB AUTO_INCREMENT=2190385211 DEFAULT CHARSET=utf8
,並(通過主義顯然產生)慢查詢:
SELECT
r0_.user_id AS user_id0, COUNT(r0_.id) AS sclr1
FROM
request r0_
WHERE
r0_.apikey = 'XXX' AND r0_.rows > 0 AND r0_.timestamp >= '2015-09-15 00:00:00' AND r0_.timestamp < '2015-10-15 00:00:00'
GROUP BY r0_.user_id
HAVING sclr1 > 0
ORDER BY sclr1 DESC
LIMIT 500
當EXPLAIN
ing查詢MySQL表示它使用apikey_timestamp_rows_idx
索引。
稍微的上下文:我們想知道,對於給定的API密鑰,每個用戶在給定的時間段內發送的請求數量爲rows > 0
。
該表目前約有22億行。
我們來看看實際的查詢和SHOW CREATE TABLE。分區不一定會比組合索引做得更好。 –
我在表格模式和查詢中添加了我的問題 –