我在MySQL 5.7上使用InnoDB引擎。
我有一张表,其中一列是(非唯一的)三字母国家代码(例如新加坡的“SGP”,日本的“JPN”等)。
对于我的大多数查询,此国家/地区代码列是我过滤的第一个WHERE子句(例如WHERE COUNTRY_CODE = 'SGP'
)
因此,我希望通过此列(子)对表进行分区。由于我的大多数查询都在一个国家/地区代码上,因此它们只会以这种方式命中一个分区。
但是,由于存在大量不同的国家/地区代码,我不想使用LIST分区,因为我必须明确地为每个国家/地区代码提供服务。
所以我使用了KEY分区,有8个分区。我认为密钥分区,即值被散列,会在8个分区上给出一个或多或少的均匀分布(不必完美)。
然而,我所经历的是,在8个分区中,其中4个完全没有受到影响。
这是我的CREATE TABLE语句的摘要:
CREATE TABLE TBL_EATING_PLACES (
ID INT UNSIGNED AUTO_INCREMENT NOT NULL,
TYPE_OF_FOOD SMALLINT UNSIGNED NOT NULL,
SUBTYPE_OF_FOOD SMALLINT UNSIGNED NOT NULL,
COUNTRY_CODE CHAR(3) NOT NULL,
ADDRESS VARCHAR(255),
...
OTHER_NON_RELEVANT_COLUMNS ...,
...,
CONSTRAINT PKEY PRIMARY KEY (ID, TYPE_OF_FOOD, SUBTYPE_OF_FOOD, COUNTRY_CODE)
)
ENGINE = InnoDB
PARTITION BY LIST COLUMNS(TYPE_OF_FOOD, SUBTYPE_OF_FOOD) SUBPARTITION BY KEY(COUNTRY_CODE) SUBPARTITIONS 8 (
PARTITION P_1_1 VALUES IN ((1, 1)),
PARTITION P_1_2 VALUES IN ((1, 2)),
PARTITION P_2_1 VALUES IN ((2, 1)),
PARTITION P_1_2 VALUES IN ((2, 2)),
PARTITION P_1_3 VALUES IN ((2, 2)),
);
我是如何进行KEY分区的,这样最终只能击中一半的分区?
答案 0 :(得分:1)
密钥分区有什么问题?它提供零利益。不要使用它。而是提供与您的查询匹配的合适复合索引。
(已添加以解决评论中的问题......)
通常,复合索引可以执行与分区相同的操作。 "分区键" "分区修剪"选择要查看的一个(或几个)分区。通过使用"分区键"作为索引中的第一列,您将获得相同的效果。 (是的,也有例外。)
分区有一些开销。每个分区都是一个文件;打开文件很昂贵。在某些情况下,在进行修剪之前会打开所有分区。过去,INSERT
没有修剪。 (哎呀!)(其中一些问题已在较新版本中得到解决,但仍有一些开销。)
我已经看过很多子分区和非RANGE分区的例子。我只看到4个案例,其中索引没有做到"好的"作为分区。我假设你发现我的博客列出了4.这里有一个副本:Partition Maintenance。
二维搜索需要减少搜索空间"。这是4例中的一例。 RANGE分区处理一个维度,PRIMARY KEY处理另一个维度。这对Find the 10 nearest pizza parlors有效(但代码混乱)。
BY RANGE是唯一可以处理'范围的分区。值(例如日期范围)。 HASH只会搜索所有分区。
BY LIST 可能与BY RANGE一样好,但仅限于精确值。然后我回过头来说"为什么不把分区键放在你原本使用的索引的前面"!
如果有人能找到第5个用例,我无法在不进行分区的情况下提供相同的性能,我将很乐意增加我的博客。