分区与额外的数据库
Partitioning vs extra database
在我工作的地方,我们进退两难。我们正在使用一个数据库 (MariaDB 10),它有 1 table 并且正在变得非常大(在我写这篇文章时是 107.4GiB,所以有 118.1 万行..)。这当然会影响系统的性能。
我和一位同事进行了讨论,他建议在 table 上使用分区。这可能会提高性能,但不会减小数据库的大小。
然而,在以前的时候,我一直致力于编写一个 cronjob,它将 2 年前的数据从 table 移动到另一个位置的数据库的精确副本。
我觉得这是更有效的方法。我希望这样做不仅会提高性能(除了 cronjob 为 运行 的时候),而且我知道它还会减小 table 的大小。
我们不希望我们的客户对这些旧数据感兴趣。
问题是:你会选择什么?我更喜欢我的选择,因为无论如何都不使用旧数据并且它使主数据库更干净,我的同事更喜欢他的解决方案,因为这意味着始终减少负载并且客户仍然可以访问旧数据。
我已经阅读了一些使用分区的专家,但还没有找到分区和将旧数据移动到另一个之间的比较 database/place
问题中的 table 使用了多个查询,这是最重要的插入:
INSERT INTO ".$defaultDataTable." (
sensor_data_type_id,
sequence_number,
value,
flag,
datetime
) VALUES (
'".Database::esc($sdtid)."',
'".Database::esc($valueSequence)."',
'".Database::esc($value)."',
'".Database::esc($valueSensorDataFlagsExtended)."',
'".Database::esc($valueDateTime)."'
);
在应用程序的多个页面中选择了数据,但以下是1个示例。
SELECT
ws_sensor_data_type.sensor_data_type_id as sensor_data_type_id,
ws_sensor_data_type.name as sensor_data_type_name,
ws_sensor_data_type.equation_id as equation_id,
ws_sensor.name as sensor_name,
ws_equation.description as data_type_name,
ws_basestation.network_id as network_id,
ws_basestation.name as basestation_name,
ws_basestation.worldwide_id as worldwide_id,
ws_client.name as client_name,
ws_sensor.device_type_id as device_type,
ws_sensor.device_id as device_id
FROM
ws_sensor_data_type,
ws_sensor,
ws_basestation,
ws_client_basestation,
ws_client,
ws_equation
WHERE ws_sensor.sensor_id = ws_sensor_data_type.sensor_id
AND ws_sensor.basestation_id = ws_basestation.basestation_id
AND ws_basestation.basestation_id = ws_client_basestation.basestation_id
AND ws_client_basestation.client_id = ws_client.client_id
AND ws_sensor_data_type.equation_id = ws_equation.equation_id
AND ws_sensor_data_type.sensor_data_type_id = '".Database::esc($sdtid)."'
");
在此示例中,选择了数据以及一些其他信息来创建 .CSV 导出文件。
create table 语句将在我创建开发数据库副本时执行,以测试分区。
我们不使用 UUID,所以这应该不是问题。
视情况而定。
分区本身并不能提高性能。只有非常有限的用例显示 any 性能改进。 More details.
如果您只从 table 中获取 "recent" 行并且您有足够的索引,那么 "neither" 就是答案——您的百万行可以增长到十亿行而无需任何性能下降。
如果你使用 UUID,那你就完蛋了。一旦数据太大而无法缓存,性能就会急剧下降。
您已经完成了一些 "hand waving"。我也是。如果您想继续讨论,请提供更多细节。 CREATE TABLE
、示例查询、提议的分区机制、提议的访问 'old' 数据的机制等
在我工作的地方,我们进退两难。我们正在使用一个数据库 (MariaDB 10),它有 1 table 并且正在变得非常大(在我写这篇文章时是 107.4GiB,所以有 118.1 万行..)。这当然会影响系统的性能。 我和一位同事进行了讨论,他建议在 table 上使用分区。这可能会提高性能,但不会减小数据库的大小。 然而,在以前的时候,我一直致力于编写一个 cronjob,它将 2 年前的数据从 table 移动到另一个位置的数据库的精确副本。 我觉得这是更有效的方法。我希望这样做不仅会提高性能(除了 cronjob 为 运行 的时候),而且我知道它还会减小 table 的大小。 我们不希望我们的客户对这些旧数据感兴趣。
问题是:你会选择什么?我更喜欢我的选择,因为无论如何都不使用旧数据并且它使主数据库更干净,我的同事更喜欢他的解决方案,因为这意味着始终减少负载并且客户仍然可以访问旧数据。
我已经阅读了一些使用分区的专家,但还没有找到分区和将旧数据移动到另一个之间的比较 database/place
问题中的 table 使用了多个查询,这是最重要的插入:
INSERT INTO ".$defaultDataTable." (
sensor_data_type_id,
sequence_number,
value,
flag,
datetime
) VALUES (
'".Database::esc($sdtid)."',
'".Database::esc($valueSequence)."',
'".Database::esc($value)."',
'".Database::esc($valueSensorDataFlagsExtended)."',
'".Database::esc($valueDateTime)."'
);
在应用程序的多个页面中选择了数据,但以下是1个示例。
SELECT
ws_sensor_data_type.sensor_data_type_id as sensor_data_type_id,
ws_sensor_data_type.name as sensor_data_type_name,
ws_sensor_data_type.equation_id as equation_id,
ws_sensor.name as sensor_name,
ws_equation.description as data_type_name,
ws_basestation.network_id as network_id,
ws_basestation.name as basestation_name,
ws_basestation.worldwide_id as worldwide_id,
ws_client.name as client_name,
ws_sensor.device_type_id as device_type,
ws_sensor.device_id as device_id
FROM
ws_sensor_data_type,
ws_sensor,
ws_basestation,
ws_client_basestation,
ws_client,
ws_equation
WHERE ws_sensor.sensor_id = ws_sensor_data_type.sensor_id
AND ws_sensor.basestation_id = ws_basestation.basestation_id
AND ws_basestation.basestation_id = ws_client_basestation.basestation_id
AND ws_client_basestation.client_id = ws_client.client_id
AND ws_sensor_data_type.equation_id = ws_equation.equation_id
AND ws_sensor_data_type.sensor_data_type_id = '".Database::esc($sdtid)."'
");
在此示例中,选择了数据以及一些其他信息来创建 .CSV 导出文件。
create table 语句将在我创建开发数据库副本时执行,以测试分区。
我们不使用 UUID,所以这应该不是问题。
视情况而定。
分区本身并不能提高性能。只有非常有限的用例显示 any 性能改进。 More details.
如果您只从 table 中获取 "recent" 行并且您有足够的索引,那么 "neither" 就是答案——您的百万行可以增长到十亿行而无需任何性能下降。
如果你使用 UUID,那你就完蛋了。一旦数据太大而无法缓存,性能就会急剧下降。
您已经完成了一些 "hand waving"。我也是。如果您想继续讨论,请提供更多细节。 CREATE TABLE
、示例查询、提议的分区机制、提议的访问 'old' 数据的机制等