2015-10-27 29 views
1

问候。为什么mariadb分区不会给我更好的性能?

让我先表明我的表方案:

CREATE TABLE `log_table` (
`rid` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
`dataId` int(10) unsigned NOT NULL DEFAULT '0', 
`memberId` int(10) unsigned NOT NULL DEFAULT '0', 
`clientId` int(10) unsigned NOT NULL DEFAULT '0', 
`qty` int(11) NOT NULL DEFAULT '0', 
`timestamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', 
`typeA` tinyint(2) DEFAULT NULL, 
`typeB` int(11) DEFAULT '0', 
PRIMARY KEY (`rid`,`timestamp`), 
KEY `idx_report1` (`timestamp`,`memberId`,`dataId`), 
KEY `idx_report2` (`memberId`,`timestamp`), 
KEY `idx_report3` (`dataId`,`timestamp`,`rid`), 
KEY `idx_report4` (`timestamp`,`typeB`,`typeA`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 
PARTITION BY RANGE (year(`timestamp`)) 
(PARTITION p2014 VALUES LESS THAN (2015), 
PARTITION p2015 VALUES LESS THAN (2016) 
); 

我使用MariaDB的5.5及该表包括25万条记录,所以我决定把表中的分区,以防止性能问题的可能发生不远的将来。 您可能会看到它是时间序列,日志数据和4个视图。例如,其中一个视图使用以下查询:

select typeB, typeA, count(*) as number from log_table where timestamp between '2015-1-1' and '2015-2-1' group by typeB, typeA; 

AFAIK,此查询仅通过分区修剪加载来自p2015的数据。但是我发现查询执行时间中原始表和分区版本没有太大的区别。 (平均1.94秒和1.95秒)

嗯,我认为它可能会受到每个分区中行数的影响。那么更小尺寸的分区如何呢? TO_DAYS()?

PARTITION BY RANGE (to_days(`timestamp`)) 
(
... 
PARTITION p_2015_01 VALUES LESS THAN (to_days('2015-2-1')), 
PARTITION p_2015_02 VALUES LESS THAN (to_days('2015-3-1')) 
... 
) 

好的,没有效果。你能不能让我知道我缺少的东西是什么?


编辑:抱歉我的错误在查询..顺便说一句,解析PARTITION不帮我。

,并解释这两个表的结果是:

// original 
+------+-------------+-----------+-------+-------------------------+-------------+---------+------+---------+-----------------------------------------------------------+ 
| id | select_type | table  | type | possible_keys   | key   | key_len | ref | rows | Extra              | 
+------+-------------+-----------+-------+-------------------------+-------------+---------+------+---------+-----------------------------------------------------------+ 
| 1 | SIMPLE  | org_table | range | idx_report1,idx_report4 | idx_report4 | 8  | NULL | 8828000 | Using where; Using index; Using temporary; Using filesort | 
+------+-------------+-----------+-------+-------------------------+-------------+---------+------+---------+-----------------------------------------------------------+ 


//partition 
+------+-------------+-----------+-------+-------------------------+-------------+---------+------+---------+-----------------------------------------------------------+ 
| id | select_type | table  | type | possible_keys   | key   | key_len | ref | rows | Extra              | 
+------+-------------+-----------+-------+-------------------------+-------------+---------+------+---------+-----------------------------------------------------------+ 
| 1 | SIMPLE  | log_table | range | idx_report1,idx_report4 | idx_report4 | 8  | NULL | 7902646 | Using where; Using index; Using temporary; Using filesort | 
+------+-------------+-----------+-------+-------------------------+-------------+---------+------+---------+-----------------------------------------------------------+ 
+0

你的解释计划是什么样的查询?顺便说一句好帖子+1 – BK435

+0

你的表中没有recdate字段。那么,你能否更新查询或创建表来相互匹配?请发布结果以解释这两个查询。我怀疑recdate字段是索引的,加上记录按日期存储在一个日志表中,因此执行时间差别很小。 – Shadow

回答

1

PARTITIONing没有帮助的性能几乎一样经常用户的事情会的。

KEY `idx_report4` (`timestamp`,`typeB`,`typeA`) 

没有分区是您提供的SELECT的最佳选择。 PARTITIONing不会加速任何。

由于BETWEEN是“包含”where timestamp between '2015-1-1' and '2015-2-1'实际上碰到两个分区。使用EXPLAIN PARTITIONS SELECT ...可以看到。

BY RANGE (TO_DAYS(...))可能好于BY RANGE (YEAR(...)),但对于给定的查询仍然没有用。

这里是我的只有 4使用情况的讨论,其中PARTITIONing有助于提高性能:http://mysql.rjweb.org/doc.php/partitionmaint

如果这种类型的查询是非常重要的,可以考虑“汇总表”为大大加快了应用程序的方式:http://mysql.rjweb.org/doc.php/datawarehousehttp://mysql.rjweb.org/doc.php/summarytables

+0

感谢您的回答。 – glowseed

相关问题