Mysql 是否有一个一般规则,用于按主键索引的顺序放置分区键?

Mysql 是否有一个一般规则,用于按主键索引的顺序放置分区键?,mysql,database-partitioning,Mysql,Database Partitioning,假设我在每个查询中都正确地查询了分区键。是否有合理的理由将分区键放在第一行以外的任何位置? 我觉得关于索引的工作原理,有些东西我还不了解。假设MySQL和InnoDB 我想我明白了,通常情况下,你会先放置选择性最强的键,然后再放置选择性较弱的键。分区密钥通常是选择性较差的密钥之一。但是,如果每个查询中都包含分区键,那么首先包含分区键又有什么区别呢?这在其他方面不是也有帮助吗?例如,如果分区键位于主键索引的前面,我就不必在每个索引中都包含分区键:使用其他索引的查询可以从主键索引借用主键,这与最左边

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

我觉得关于索引的工作原理,有些东西我还不了解。假设MySQL和InnoDB

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

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

例如:

或者

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
是主键的第一列,这将执行分区修剪,并且还使用主键索引,因为您的搜索项位于第一列

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 |
+----+-------------+-------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
mysql>explain partitions从fee中选择*其中fi=175并在

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

这两列的选择性并不像一些人认为的那样重要

如果要按以下方式查询表:

SELECT ... FROM fee WHERE fi=? AND fo=?
那么,如果它通过
fi,fo
fo,fi
搜索B-树,又有什么关系呢?它最终会找到相同的记录,并且需要大致相同的步骤。理论上是有区别的,但在大多数情况下,这不会产生重大区别

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

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

SELECT ... FROM fee WHERE fi=?
如果
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         | 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 |
+----+-------------+-------+------------+-------+---------------+------------+---------+------+------+----------+-----------------------+
mysql>explain partitions从fee中选择*其中fi=175并在
这里我们看到
fi
r上的条件