有没有一个通用规则,按照主键索引的顺序将分区键放在哪里



假设我在每个查询中都正确地查询分区键。有没有合理的理由将分区键放在第一行以外的任何位置

我觉得我对这个指数的运作方式有些不了解。假设MySQL和InnoDB。

我想我明白了,通常情况下,你会把最有选择性的钥匙放在第一位,然后把不太有选择性的放在第二位。分区键通常是选择较少的键之一。但是,如果每个查询中都包含分区键,那么首先包含分区键有什么区别?这在其他方面也有帮助吗?例如,如果分区键在主键索引的前面,我就不必在每个索引中都包含它:使用其他索引的查询可以从主键索引中借用主键,这与最左边的键约束一致。

我不知道一个索引本身是否被分区,但如果它是一个覆盖索引,它似乎可以被分区。(我说得对吗?(如果是这样,分区键必须是第一个,否,分区才能工作?

例如:

CREATE TABLE  `fee` (
`fi` INT ,
`fo` INT ,
PRIMARY KEY ( `fi` , `fo` ) ,
) ENGINE = INNODB
PARTITION BY RANGE ( `fi` ) (
. . .
);

或者。

CREATE TABLE  `fee` (
`fi` INT ,
`fo` INT ,
PRIMARY KEY ( `fo` , `fi` ) ,
) ENGINE = INNODB
PARTITION BY RANGE ( `fi` ) (
. . .
);

哪一个,如果有,本质上更好,为什么或为什么不?

谢谢你抽出时间。

这两列的选择性并不像一些人想象的那么重要。

如果您将表格查询为:

SELECT ... FROM fee WHERE fi=? AND fo=?

那么,它是按fi,fo还是按fo,fi搜索B树又有什么关系呢?它最终会找到相同的记录,并且需要大致相同数量的步骤才能做到这一点。理论上存在差异,但在大多数情况下不会产生显著差异。

更重要的是,如果查询只搜索主键的一列或另一列。

您提到所有查询都在分区列上搜索,在本例中为fi。您是否有在fi上搜索但不在fo上搜索的查询?

SELECT ... FROM fee WHERE fi=?

如果fi是主键的第一列,这将进行分区修剪,并且还使用primary key索引,因为搜索词位于第一列。

mysql> explain partitions select * from fee where fi = 175;
+----+-------------+-------+------------+------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key     | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+---------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | fee   | p2         | ref  | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+---------+---------+-------+------+----------+-------+

而如果fi是主键的第二列,那么它可以进行分区修剪,但不使用索引。

mysql> explain partitions select * from fee where fi = 175;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | fee   | p2         | ALL  | NULL          | NULL | NULL    | NULL |    1 |   100.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+

索引也被分区。将分区视为一系列完全独立的表,具有相同的列和索引,只是行的子集。一旦查询确定了要读取哪个分区,它就按照对未分区表执行查询的方式执行查询,根据查询条件选择索引。它会使用主键进行搜索吗?

mysql> explain partitions select * from fee where fi = 175 and created_at < now();
+----+-------------+-------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type  | possible_keys | key        | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+-------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | fee   | p2         | range | created_at    | created_at | 6       | NULL |    1 |   100.00 | Using index condition |
+----+-------------+-------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+

在这里,我们看到fi上的条件导致了分区修剪,但优化器更喜欢created_at上的索引。它在相应的分区中搜索该索引。

"你把最有选择性的键放在第一位,把不太有选择性的放在后面"——不,那是老太太的故事。

将使用"="测试的键放在第一位是一个简单而重要的规则。

将复合InnoDB BTree索引想象成这样工作。将所有列连接在一起,然后将BTree想象为具有单个字符串作为键。

将";分区键";索引中的第一个是最不有用的地方!你已经在修剪了;把它放在索引中实际上是多余的。但是,对于任何Unique键(包括"PRIMARY key"(,都是必需的

是的,您正确地观察到PK列隐含地包含在每个辅助密钥中,因此分区密钥也包含在内。

请注意,如果分区键实际上不是所需UNIQUE键的一部分,那么唯一性约束是不可能的(在MySQL中(。然而,附加PK不是唯一性约束的一部分。由于MySQL只愿意检查一个分区的唯一性,因此必须包含分区密钥,以提供状态为"的语义;独特的";整个桌子。(是的,这有点复杂;接受它吧。(

在您的示例中,如果执行SELECT .. WHERE fi BETWEEN 1 and 2AND fo=3,则以fi开始的任何索引(PK是一个索引(都将比fo在索引中第一个更难工作。

因此,经验法则是将分区键移动到包含它的任何索引的。(我只看到过一个罕见的异常;我忘记了细节。(

相关内容

  • 没有找到相关文章

最新更新