1

背景

我有一张很大的桌子,桌子是这样的

CREATE TABLE tb_doc (
did mediumint(8) unsigned NOT NULL auto_increment, 
title varchar(80) NOT NULL default '',
...,
PRIMARY KEY  (did), 
KEY title (title)
) 
TYPE=MyISAM;

title 的类型是 varchar(80),大多数时候 title 会是纯数字字符串,比如 '111111','2222222','44444444',有时会是 utf-8 字符串,比如 '3a','a4 ' 或“中国”(汉字)。

我已经使用 HASH (did) 进行分区,但我的 SELECT 语句总是像

SELECT did, title,... FROM tb_doc WHERE title= '1111111';
SELECT did, title,... FROM tb_doc WHERE title= '2222222';

所以我想用title来做分区,希望这样会更快。现在问题来了。

实验

我使用了以下语句:

PARTITION BY RANGE COLUMNS (title)(
PARTITION p00 VALUES LESS THAN (1),         # not pure number strings
PARTITION p01 VALUES LESS THAN (500000),    # pure number strings from 1 to 500k
PARTITION p02 VALUES LESS THAN (1000000),   # pure number strings from 500k to 1000k
PARTITION p03 VALUES LESS THAN (1500000),   # pure number strings from 1000k to 1500k
..........                                  # ......    

PARTITION pn VALUES LESS THAN (25000000),   # the biggest number now
)
;

类似问题

我阅读了以下两个问答: 在 MySQL 中对数据库表 进行分区 如何在 Mysql 中使用 LIKE 标准对表进行分区, 但它们适用于英语世界,不适用于我的情况。

问题

  1. 用title来做partition比较好,对吧?
  2. 你能给我一个“utf-8”范围的例子吗?我尝试了'500000','1000000',...,但它们不起作用。
  3. 如果我使用 SELECT xxx from tb_doc WHERE title='12345',MySQL 只从第 1 部分获取数据?
  4. 这张表是~50GB,多少个分区是最佳的?

先感谢您。

4

2 回答 2

1

请注意,VARCHAR正确存储多种语言的字符会出现问题,更好地使用NVARCHAR.

HASH 分区用于在分区上平均分配负载。我想说,首先你应该用对人类有意义的东西进行分区(列经常出现在 Where 子句中),然后进行 HASH 子分区以同时利用尽可能多的核心。因此,在这种情况下,HASH 子分区的数量将 <= 没有核心。

我建议您在title列上创建一个聚集索引。这将加快您的查询速度。

关于你的问题:

  1. 不一定。由于聚集索引而不是分区,它将加快查询速度。使用分区来管理表:例如。快速删除许多行。如果您的查询中有很大一部分查找多行(不仅仅是 1 行)或者title不是一UNIQUE列,那么您可以考虑分区

  2. 作为 UTF-8 分区边界的示例,我会说:less then ('c')

  3. 根据您定义分区的方式,它可能会命中 1 个、多个或所有分区。

  4. 拥有许多分区不会有任何损失,但 MySQL 5.5+ 中的表最多可以有 1024 个分区和子分区。

当您要按字符串值进行分区时,请KEY PARTITIONING按照此处所述使用:18.2.5。键分区

例子:

CREATE TABLE tm1 (
    s1 CHAR(32) PRIMARY KEY
)
PARTITION BY KEY(s1)
PARTITIONS 10;

将分区数设置为与您的字母表中的字母(或您预期在表中看到的所有字母表)相同。

于 2013-05-29T11:42:12.757 回答
0

分区title,即使你能做到,也不会加速

SELECT did, title,... FROM tb_doc WHERE title= '1111111';

有关 PARTITIONing 的限制的进一步讨论,以及它会有所帮助的几个用例,请参阅我的博客

于 2015-11-26T06:27:22.130 回答