MySQL 大型数据集

MySQL Large Datasets

我有大量数据。我在 MySQL table 中加载了超过 40GB。我正在尝试执行像 select * from tablename 这样的简单查询,但是 运行 需要花费大量时间并最终超时。如果我设置一个限制,执行速度相当快,例如:select * from tablename limit 1000。 table 有超过 2 亿条记录。

关于使用这些类型的数据集有什么技巧吗?

对于大型数据库,应考虑使用 Apache Spark 等替代解决方案。 MySQL 从磁盘读取数据,这是一个缓慢的操作。没有什么比基于 MapReduce 的技术更快。看看this answer。确实,对于大型数据库,查询变得非常具有挑战性。

无论如何,假设您想坚持使用 MySQL,首先,如果您使用的是 MyISAM,请确保将数据库存储转换为 InnoDB。如果您有很多 read/write 操作,这一点尤其重要。

分区也很重要,将 table 减少为更易于管理的较小 table。它还将提高索引性能。

添加索引不要太大方。明智地定义索引。如果索引不需要 UNIQUE,则不要将其定义为一个。如果一个索引不需要包含多个字段则不包含多个字段。

最重要的是开始监控您的 MySQL 实例。使用 SHOW ENGINE INNODB STATUS 调查 MySQL 实例的性能。

您需要做的第一件事是完全忽略所有建议其他一些令人敬畏的庞然大物技术的答案和评论。这绝对是胡说八道。这些东西不能以不同的方式工作,因为它们都受到相同问题的限制 - 硬件。

现在,让我们回到MySQL。 LIMIT 的问题在于 MySQL 获取了 整个 数据集,然后获取了 LIMITOFFSET 开始的行数。这意味着如果你这样做 SELECT * FROM my_table LIMIT 1000 - 它将获取所有 2 亿行,缓冲它们,然后它将开始从 0 到 999 计数并丢弃其余的。

是的,这需要时间。是的,它看起来很愚蠢。但是,MySQL 不知道 "start" 或 "end" 是什么意思,所以在您告诉它之前它无法知道限制和偏移量是什么。

为了改进您的搜索,您可以使用类似这样的东西(假设您有数字主键):

SELECT * FROM tablename WHERE id < 10000 LIMIT 1000;

在这种情况下,MySQL 将处理 PK 低于 10 000 的所有行,而不是 2 亿行。更容易、更快,也可读。数字可以随时调整,如果您使用脚本语言执行某种分页,您始终可以传输出现的最后一个数字 ID,因此 MySQL 可以从该 ID 开始搜索。

此外,您应该使用 InnoDB 引擎,并使用 innodb_buffer_pool_size 对其进行调整,这是让 MySQL 飞起来的神奇调味料。