CREATE TABLE ofRoster (
`rosterID` bigint(20) NOT NULL,
`username` varchar(64) NOT NULL,
`jid` varchar(1024) NOT NULL,
`sub` tinyint(4) NOT NULL,
`ask` tinyint(4) NOT NULL,
`recv` tinyint(4) NOT NULL,
`nick` varchar(255) DEFAULT NULL,
PRIMARY KEY (`rosterID`),
KEY `ofRoster_unameid_idx` (`username`),
KEY `ofRoster_jid_idx` (`jid`(255))
) ENGINE=InnoDB;
CREATE TABLE `ofRoster_par` (
`rosterID` bigint(20) NOT NULL AUTO_INCREMENT,
`username` int(64) NOT NULL,
`jid` varchar(1024) NOT NULL,
`sub` tinyint(4) NOT NULL,
`ask` tinyint(4) NOT NULL,
`recv` tinyint(4) NOT NULL,
`nick` varchar(255) DEFAULT NULL,
UNIQUE KEY `rosterID` (`rosterID`,`username`),
KEY `ofRoster_unameid_idx` (`username`),
KEY `ofRoster_jid_idx` (`jid`(255))
) ENGINE=InnoDB AUTO_INCREMENT=412595 DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (username)
PARTITIONS 10 */ ;
我在用户名上创建了分区,这样当我使用select命令时,它只需要在一个分区上搜索。 但我不确定这是否有利,因为已有用户名索引。
explain SELECT count(*) FROM ofRoster_par WHERE username='1';
+----+-------------+--------------+------+----------------------+----------------------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+------+----------------------+----------------------+---------+-------+------+-------------+
| 1 | SIMPLE | ofRoster_par | ref | ofRoster_unameid_idx | ofRoster_unameid_idx | 4 | const | 120 | Using index |
+----+-------------+--------------+------+----------------------+----------------------+---------+-------+------+-------------+
explain SELECT count(*) FROM ofRoster WHERE username='1';
+----+-------------+----------+------+----------------------+----------------------+---------+-------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+----------------------+----------------------+---------+-------+------+--------------------------+
| 1 | SIMPLE | ofRoster | ref | ofRoster_unameid_idx | ofRoster_unameid_idx | 66 | const | 120 | Using where; Using index |
目前桌面上只有40万条记录,但生产记录将在8000万左右。
两个查询所用的时间也相同: - (
答案 0 :(得分:0)
PARTITION BY HASH
是无用的。
在您的示例中,非分区表上的INDEX(username)
可能比使用PARTITION BY HASH(username)
更快。
你已经有了这样的索引。它有多快?
以下是发生的事情:
使用分区:
KEY(username)
(而不是数据)在索引中执行COUNT(*)
(注意"使用索引")没有分区:
KEY(username)
(而不是数据)在索引中执行COUNT(*)
(注意"使用索引")其他评论:
username
是唯一的,请考虑将其设为PRIMARY KEY
并删除rosterID
。 (您可能希望保留rosterID
,因为它较小并用于JOINing
到其他几个表。)INT(64)
您的意思是VARCHAR(64)
。这可能会影响您的计时测试。(jid(255))
很少有用。让我们看看你是如何使用它的。BIGINT
(8字节); INT UNSIGNED
(4个字节)可以处理400亿卢比。latin1
限制您使用西欧语言吗?EXPLAIN
与分区表一起使用时,请使用EXPLAIN PARTITIONS SELECT ...
。你可能会有一些惊喜。