分区与额外数据库

时间:2017-07-12 12:58:01

标签: mariadb database-performance partitioning

在我工作的地方,我们陷入两难境地。我们正在使用一个数据库(MariaDB 10),它有一个非常大的表(107.4GiB,因为我写这个,所以118万行..)。这当然会影响系统的性能。 我和一位同事进行了讨论,他建议在那张桌子上使用分区。这可能会提高性能,但不会减小数据库的大小。 然而,在过去,我一直致力于编写一个cronjob,它将从该表移动2年以前的数据到另一个位置的数据库的精确副本。 我觉得这是更有效的方式。我希望这样做不仅可以提高性能(除了在cronjob运行的时候),但我知道它也会减少表的大小。 无论如何,我们不希望客户对这些旧数据感兴趣。

问题是:你会选择什么?我更喜欢我的选择,因为无论如何都不使用旧数据并且它使主数据库更加清洁,我的同事更喜欢他的解决方案,因为它意味着始终减少负载,客户仍然可以访问旧数据。

我已经阅读了一些使用分区的专家,但是在分区和将旧数据移动到另一个数据库/地方之间尚未找到比较

有问题的表使用了几个查询,这是最重要的插入:

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)."'
                        );

在应用程序的几个页面中选择数据,但以下是一个示例。

            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导出文件。

创建表语句将跟随,因为我正在创建一个Development DB的副本,以测试分区。

我们不使用UUID,因此不应该是一个问题。

1 个答案:

答案 0 :(得分:1)

取决于。

分区本身并不能提高性能。只有非常有限的用例显示任何性能改进。 More details

如果你只从表中获取“最近”的行并且你有足够的索引,那么“两者都不”就是答案 - 你的百万行可以增长到十亿而不会导致性能下降。

如果您使用的是UUID,那么您将注定失败。一旦数据太大而无法缓存,性能就会大幅下降。

你做了一些“挥手”。我也是如此。如果您想继续讨论,请提供更多细节。 CREATE TABLE,示例查询,建议的分区机制,用于访问“旧”数据的建议机制等。