mysql - [索引列分区的好处]

标签 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 |

目前表上只有 400,000 条记录,但生产记录将约为 8000 万条。

两个查询所花费的时间也是相同的:-(

最佳答案

PARTITION BY HASH 在我看来,无用

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

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

这是发生的事情:

带分区:

  1. 选择分区
  2. 使用KEY(username)(而不是数据)在索引内执行COUNT(*)(注意“使用索引”)

没有分区:

  1. 使用KEY(username)(而不是数据)在索引内执行COUNT(*)(注意“使用索引”)

其他评论:

  • 如果用户名是唯一的,请考虑将其设为主键并删除rosterID。 (您可能需要保留rosterID,因为它较小并且用于JOINing到其他几个表。)
  • Bug:您说的是INT(64),而您的意思是VARCHAR(64)。这可能会影响您的计时测试。
  • “前缀索引”(jid(255)) 很少有用。让我们看看您如何使用它。
  • 80M 行不保证 BIGINT(8 字节); INT UNSIGNED(4 字节)可以处理 40 亿。
  • 您知道 latin1 限制您只能使用西欧语言吗?
  • 当对分区表使用EXPLAIN时,请使用EXPLAIN PARTITIONS SELECT ...。你可能会得到一些惊喜。

关于mysql - [索引列分区的好处],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38712320/

相关文章:

apache-spark - 在数据帧中使用 dropDuplicates 会导致分区号发生变化

postgresql - 使用 "IN"子句的存储查询结果命中所有分区

php - Doctrine2 和 MySQL 分区

c# - 将多边形切成 n block

mysql - 数据透视查询不在 mysql 上执行

mysql - 使用 Grails 数据库迁移插件创建并运行存储过程

mysql - 如何通过NodeJS插入MySQL中的Orders表和Order Items表

php - 解析多行声明版本和编码的 XML 文档时出现 SimpleXML 错误

java - 为什么 getGeneratedKeys() 返回 "GENERATED_KEY"作为列名?

mysql - 多表还是使用分区?