每天在巨大的桌子上添加和删除索引是一个好习惯吗?

Tch*_*ane 7 mysql sql database indexing

我正在构建一个连接到MySQL数据库的Web应用程序.我有两个巨大的表,目前每行约有4千万行,他们每天都会收到新行(每天增加约500 000-1000 000行).

添加新行的过程在夜间运行,而没有人可以使用该应用程序,新行的内容取决于SELECT当前数据库上的一些基本查询的结果.为了SELECT足够快地获得这些语句的结果,我在每个列中使用简单索引(每个索引一列),在WHERE子句中至少出现一次.

问题是,在白天,对这些表运行一些完全不同的查询,包括一些"范围WHERE子句"(SELECT * FROM t1 WHERE a = a1 AND b = b1 AND (date BETWEEN d1 AND d2)).我在堆栈上找到了这个非常有用的迷你食谱,根据查询数据库的方式,建议你应该使用哪些索引:http://mysql.rjweb.org/doc.php/index_cookbook_mysql 他们建议使用复合索引:in我上面的示例查询将给出INDEX(a,b,date).

它确实提高了白天运行查询的速度(从1分钟到8秒,所以我真的很高兴).

但是,使用这些复合索引,在夜间添加新行所需的时间完全爆炸(添加每日内容需要一天以上).

这是我的问题:是否可以每晚删除所有索引,添加新内容,并设置备份每日索引?或者这是危险的,因为索引不是每天都要重建,特别是在如此大的桌子上?我知道这样的操作总共需要大约两个小时(丢弃并重新创建INDEX).

我知道存在,ALTER TABLE table_name DISABLE KEYS;但我正在使用InnoDB,我相信它不适用于InnoDB表.

任何高级建议都会受到欢迎!提前致谢.

Gor*_*off 4

我相信您已经回答了自己的问题:您白天需要索引,但晚上不需要。根据您的描述,您应该在晚上删除批量插入的索引,然后重新创建它们。删除数据加载索引并非闻所未闻,并且似乎适合您的情况。

我想问一下你如何插入新数据。一种方法是一次插入一行值。另一种是将值放入临时表(没有索引)并进行批量插入:

insert into bigtable( . . .)
    select . . .
    from smalltable;
Run Code Online (Sandbox Code Playgroud)

它们具有不同的性能特征。您可能会发现使用单个insert(如果您还没有这样做)对于您的目的来说已经足够快了。