[索引列上的分区效率]

时间:2016-08-02 05:25:03

标签: mysql partitioning

 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万左右。

两个查询所用的时间也相同: - (

1 个答案:

答案 0 :(得分:0)

在我看来,

PARTITION BY HASH无用的

在您的示例中,非分区表上的INDEX(username)可能比使用PARTITION BY HASH(username)更快。

你已经有了这样的索引。它有多快?

以下是发生的事情:

使用分区:

  1. 选择分区
  2. 使用KEY(username)(而不是数据)在索引中执行COUNT(*)(注意"使用索引")
  3. 没有分区:

    1. 使用KEY(username)(而不是数据)在索引中执行COUNT(*)(注意"使用索引")
    2. 其他评论:

      • 如果username是唯一的,请考虑将其设为PRIMARY KEY并删除rosterID。 (您可能希望保留rosterID,因为它较小并用于JOINing到其他几个表。)
      • 错误:您说INT(64)您的意思是VARCHAR(64)。这可能会影响您的计时测试。
      • "前缀索引" (jid(255))很少有用。让我们看看你是如何使用它的。
      • 80M行不保证BIGINT(8字节); INT UNSIGNED(4个字节)可以处理400亿卢比。
      • 您了解latin1限制您使用西欧语言吗?
      • EXPLAIN与分区表一起使用时,请使用EXPLAIN PARTITIONS SELECT ...。你可能会有一些惊喜。