【发布时间】:2017-04-07 13:12:18
【问题描述】:
我正在构建一个连接到 MySQL 数据库的 Web 应用程序。 目前我有两个巨大的表,每个表包含大约 4000 万行,并且它们每天都会收到新行(每天增加约 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
他们建议使用复合索引:在我上面的示例查询中,它会给出 INDEX(a, b, date)。
它确实提高了白天运行查询的速度(从 1 分钟到 8 秒,所以我真的很高兴)。
但是,使用这些复合索引,在夜间添加新行所需的时间完全爆炸(添加每日内容需要超过一天的时间)。
这是我的问题:是否可以每天晚上删除所有索引,添加新内容并备份每日索引? 或者这会很危险,因为索引不是每天都要重建的,尤其是在这么大的表上? 我知道这样的操作总共需要大约两个小时(删除并重新创建索引)。
我知道ALTER TABLE table_name DISABLE KEYS; 的存在,但我使用的是 InnoDB,我相信它不适用于 InnoDB 表。
【问题讨论】:
-
如果您每天添加 500k 到 1m 行新行,最好在 1 年内您将拥有 222.5m 行,因此如果目前需要 2 小时,则比当前数量多 5 倍,假设速度的线性下降(不太可能),这将需要 10 个小时。在两年的时间里,这将花费一整天的时间,您将永远无法使用该应用程序。如果我是你,我会开始考虑表分区。此外,您是否需要以最细粒度的方式查询数据?如果不是,您可能希望查看 OLAP 数据库和/或多维数据集,以提高查询数据的效率。
-
你是对的,行数会增加,但它会达到最大数量,因为我每天都会删除超过一年的行,就在添加新行之后。无论如何,我要去看看那些 OLAP 数据库。如果你有一些很好的文档,我很乐意得到它!
标签: mysql sql database indexing