我有一个 MYSQL InnoDB 表
table
具有以下列(表和列名称已更改):
其中
rel_ab
是描述给定日期 2 个变量 var_a
和 var_b
之间关系的列。 (var_a
和var_b
参考不同的表格)
数据每天分批上传,每天总计约700万行。问题是,仅仅几周后,上传每个新的每日批次就开始需要很多小时了。显然我们需要改进我们的表设计。这是我们表格的一些其他详细信息。
COMPRESSION="zlib"
.var_a
和var_b
的索引,外键需要。SELECT * FROM table WHERE date = <date>
的查询<date>
。选择只需要几分钟。var_a
和var_b
引用的表中删除条目。df.to_sql('temp', con, if_exists='replace', index=False, method='multi')
上传,我们从 temp
到 table
插入忽略,然后删除 temp
.因此,我计划至少执行以下操作之一:
var_a
和var_b
列的外键约束,并依靠数据上传过程正确完成所有操作。这是因为在我们的用例中,这两个索引实际上都没有加快查询速度。table_230501
的表,其中包含 var_a
、var_b
、rel_ab
列。这是因为我们一次只能选择一个日期。我知道第一个解决方案可能会威胁到数据完整性,而第二个解决方案会使我们的模式变得混乱。以我有限的经验,我也从未听说过第二种选择,也无法在网上找到这种设计的任何例子。这些选项中的任何一个都是明智的解决方案吗?两者都将提高上传速度并减少磁盘使用,但也有其缺点。否则,还有什么其他方法可以提高上传速度?
有一些潜在的解决方案可以帮助您提高 MySQL 表的上传速度:
删除 var_a 和 var_b 上的索引:由于您没有使用这些索引来加速查询,删除它们有助于加快上传过程。但是,如果您使用外键约束,通常建议在属于外键的列上保留索引。
按日期对表进行分区:分区有助于提高查询性能,因为它允许数据库只扫描给定查询的相关分区。但是,它也会使维护和备份更加复杂,如果您的查询已经运行良好,则可能没有必要。
使用批量插入方法:与其使用 df.to_sql 插入单独的行,不如尝试使用批量插入方法,如 LOAD DATA INFILE 或 MySQL 批量插入 API。这可能比单个插入更快,特别是如果您可以批量上传数据而不是一次上传一行。
使用不同的压缩算法:您目前正在使用 zlib 压缩,但还有其他压缩算法可能对您的数据更快或更有效。您可以尝试使用不同的压缩选项进行试验,看看它们是否可以提高上传速度。
增加服务器资源:如果您有预算和资源,升级服务器硬件或增加服务器数量可以帮助提高上传速度。这可能不是对每个人都可行的选择,但如果您已经用尽了其他选择,则值得考虑。
就您建议的选项而言,删除外键约束可能会导致数据完整性问题,因此我不推荐这种方法。如果您的查询已经遇到性能问题,按日期分区可能是一个很好的解决方案,但如果您的查询已经快速运行,则可能没有必要。