无法分区 mysql table
cannot partition this mysql table
我有一个名为 "transaction" 的 innoDB table,大约有 150 万行。我想对这个 table 进行分区(可能在 "gas_station_id" 列上,因为它在连接查询中经常使用)但是我在 MySQL 5.7 Reference Manual 中读到
All columns used in the table's partitioning expression must be part of every unique key that the table may have, including any primary key.
我有两个问题:
- 列 "gas_station_id" 不是唯一键或主键的一部分。那我怎么分割这个table呢?
- 即使我可以对这个 table 进行分区,我也不确定在这种情况下哪种分区类型会更好? (我在考虑 LIST 分区(我们有大约 40 个不同(不同的)加油站)但我不确定,因为每个列表分区中只有一个值,如下所示:
ALTER TABLE transaction
PARTITION BY LIST(gas_station_id)
( PARTITION p1 VALUES IN (9001),
PARTITION p2 VALUES IN (9002),.....
)
- 我尝试按
KEY
进行分区,但收到以下错误(我认为是因为 id 不是所有唯一键的一部分......):
#1053 - a UNIQUE INDEX must include all columns in the table's partitioning function
这是"transaction"table的结构:
编辑
这就是 SHOW CREATE TABLE 显示的内容:
CREATE TABLE `transaction` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`terminal_transaction_id` int(11) NOT NULL,
`fuel_terminal_id` int(11) NOT NULL,
`fuel_terminal_serial` int(11) NOT NULL,
`xboard_id` int(11) NOT NULL,
`gas_station_id` int(11) NOT NULL,
`operator_id` varchar(16) NOT NULL,
`shift_id` int(11) NOT NULL,
`xboard_total_counter` int(11) NOT NULL,
`fuel_type` tinyint(2) NOT NULL,
`start_fuel_time` int(11) NOT NULL,
`end_fuel_time` int(11) DEFAULT NULL,
`preset_amount` int(11) NOT NULL,
`actual_amount` int(11) DEFAULT NULL,
`fuel_cost` int(11) DEFAULT NULL,
`payment_cost` int(11) DEFAULT NULL,
`purchase_type` int(11) NOT NULL,
`payment_ref_id` text,
`unit_fuel_price` int(11) NOT NULL,
`fuel_status_id` int(11) DEFAULT NULL,
`fuel_mode_id` int(11) NOT NULL,
`payment_result` int(11) NOT NULL,
`card_pan` varchar(20) DEFAULT NULL,
`state` int(11) DEFAULT NULL,
`totalizer` int(11) NOT NULL DEFAULT '0',
`shift_start_time` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `terminal_transaction_id` (`terminal_transaction_id`,`fuel_terminal_id`,`start_fuel_time`) USING BTREE,
KEY `start_fuel_time_idx` (`start_fuel_time`),
KEY `fuel_terminal_idx` (`fuel_terminal_id`),
KEY `xboard_idx` (`xboard_id`),
KEY `gas_station_id` (`gas_station_id`) USING BTREE,
KEY `purchase_type` (`purchase_type`) USING BTREE,
KEY `shift_start_time` (`shift_start_time`) USING BTREE,
KEY `fuel_type` (`fuel_type`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1665335 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT
简短回答:不要使用 PARTITION。让我们看看查询以帮助加快速度。
长答案:
- 150 万行仅略微大到可以考虑分区。
- PARTITION BY LIST 可能对性能没有用。
- 您没有提供足够的信息来给您其他模糊提示的答案。请至少提供
SHOW CREATE TABLE
和较慢的 SELECT
.
- 可以将分区键添加到
PRIMARY
或 UNIQUE
键的末尾;您将失去唯一性测试。
- 不要索引低基数列;它不会被使用。
我有一个名为 "transaction" 的 innoDB table,大约有 150 万行。我想对这个 table 进行分区(可能在 "gas_station_id" 列上,因为它在连接查询中经常使用)但是我在 MySQL 5.7 Reference Manual 中读到
All columns used in the table's partitioning expression must be part of every unique key that the table may have, including any primary key.
我有两个问题:
- 列 "gas_station_id" 不是唯一键或主键的一部分。那我怎么分割这个table呢?
- 即使我可以对这个 table 进行分区,我也不确定在这种情况下哪种分区类型会更好? (我在考虑 LIST 分区(我们有大约 40 个不同(不同的)加油站)但我不确定,因为每个列表分区中只有一个值,如下所示:
ALTER TABLE transaction PARTITION BY LIST(gas_station_id) ( PARTITION p1 VALUES IN (9001), PARTITION p2 VALUES IN (9002),.....
) - 我尝试按
KEY
进行分区,但收到以下错误(我认为是因为 id 不是所有唯一键的一部分......):
#1053 - a UNIQUE INDEX must include all columns in the table's partitioning function
这是"transaction"table的结构:
编辑 这就是 SHOW CREATE TABLE 显示的内容:
CREATE TABLE `transaction` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`terminal_transaction_id` int(11) NOT NULL,
`fuel_terminal_id` int(11) NOT NULL,
`fuel_terminal_serial` int(11) NOT NULL,
`xboard_id` int(11) NOT NULL,
`gas_station_id` int(11) NOT NULL,
`operator_id` varchar(16) NOT NULL,
`shift_id` int(11) NOT NULL,
`xboard_total_counter` int(11) NOT NULL,
`fuel_type` tinyint(2) NOT NULL,
`start_fuel_time` int(11) NOT NULL,
`end_fuel_time` int(11) DEFAULT NULL,
`preset_amount` int(11) NOT NULL,
`actual_amount` int(11) DEFAULT NULL,
`fuel_cost` int(11) DEFAULT NULL,
`payment_cost` int(11) DEFAULT NULL,
`purchase_type` int(11) NOT NULL,
`payment_ref_id` text,
`unit_fuel_price` int(11) NOT NULL,
`fuel_status_id` int(11) DEFAULT NULL,
`fuel_mode_id` int(11) NOT NULL,
`payment_result` int(11) NOT NULL,
`card_pan` varchar(20) DEFAULT NULL,
`state` int(11) DEFAULT NULL,
`totalizer` int(11) NOT NULL DEFAULT '0',
`shift_start_time` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `terminal_transaction_id` (`terminal_transaction_id`,`fuel_terminal_id`,`start_fuel_time`) USING BTREE,
KEY `start_fuel_time_idx` (`start_fuel_time`),
KEY `fuel_terminal_idx` (`fuel_terminal_id`),
KEY `xboard_idx` (`xboard_id`),
KEY `gas_station_id` (`gas_station_id`) USING BTREE,
KEY `purchase_type` (`purchase_type`) USING BTREE,
KEY `shift_start_time` (`shift_start_time`) USING BTREE,
KEY `fuel_type` (`fuel_type`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1665335 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT
简短回答:不要使用 PARTITION。让我们看看查询以帮助加快速度。
长答案:
- 150 万行仅略微大到可以考虑分区。
- PARTITION BY LIST 可能对性能没有用。
- 您没有提供足够的信息来给您其他模糊提示的答案。请至少提供
SHOW CREATE TABLE
和较慢的SELECT
. - 可以将分区键添加到
PRIMARY
或UNIQUE
键的末尾;您将失去唯一性测试。 - 不要索引低基数列;它不会被使用。