-2

下面的查询需要大约一分钟才能在我的 MySQL 实例上运行(运行在一台相当强大的机器上,该机器具有 64G 内存、2T 磁盘、2.30Ghz CPU,具有 8 个内核和 16 个逻辑,并且查询在 localhost 上运行)。同样的查询在我有权访问的 SQL Server 数据库上运行不到一秒。不幸的是,我无法访问 SQL Server 主机或 DBA 等。

select min(visit_start_date)
from visit_occurrence;

该表已设置为ENGINE=MyISAMdefault-storage-engine=INNODBinnodb_buffer_pool_size=16G设置在 中my.ini

是否有一些我可能缺少的配置会导致此查询在 MySQL 上运行如此缓慢?我该如何解决?

我有大量需要支持的表和查询,所以我真的希望能够在全球范围内解决这个问题,而不是在我有慢查询的地方创建索引。

SQL Server 数据库似乎没有关于正在查询的列的索引,如下所示。

在此处输入图像描述


编辑:

  • 未标记的 MS Sql Server,我已标记它希望我们的 MS Sql Server 同事的帮助与信息,Sql Server 有一些结构化数据和/或查询的方式,这将使这种类型的查询在该平台上运行得更快,例如mysql

  • 删除了代码图像以更符合社区标准

  • 如果你不问,你永远不知道是否有一个神奇的快速按钮(ENGINE=MyISAM 有时有点像 MySql 中某些查询的神奇快速按钮)。我有点想在这里寻找潜在的硬件或集群解决方案。Apache Ignite 是一个潜在的解决方案吗?

再次感谢社区的所有支持和帮助。我希望这可以解决这篇文章中提出的大部分问题。


第二次编辑:下面链接中描述的分区/分片是否是一个潜在的解决方案?

https://user3141592.medium.com/how-to-scale-mysql-42ebd2841fa6

https://dev.mysql.com/doc/refman/8.0/en/partitioning-overview.html


第三次编辑:关于社区标准的说明。

我们的社区标准的一部分是明确地欢迎、包容和友善。

https://stackoverflow.blog/2018/04/26/stack-overflow-isnt-very-welcoming-its-time-for-that-to-change/?fbclid=IwAR1gr6r2qmXs506SAV3H_h6H8LoFy3mlXucfa-fqiiEXMHUR3aF_tdoZGsw

https://meta.stackexchange.com/questions/240839/the-new-new-be-nice-policy-code-of-conduct-updated-with-your-feedback)。

这里使用了 MS Sql Server 标记,因为我要比较的系统之一是 MS Sql Server。我们真的在这里使用非常有限的信息。我有两个系统:我的 MySql 系统,在我运行它时就知道了,而 MS Sql Server 在其他人的系统中运行相同的数据库,我对此知之甚少(我只有一个只读的 sql 提示符) . 我在比较苹果和橙子:相同的查询在橙子(MS Sql Server)上运行良好,但在苹果(MySql 实例)上运行不佳。我想知道为什么,这样我就可以就如何让我的查询在合理的时间内运行做出明智的决定。如何让我的苹果看起来像橘子?我要切换到 MS Sql Server 吗?我需要部署在不同的硬件上吗?另一个系统是否在其数据库实例之上运行某种内存缓存系统?大多数这些可能性都需要大量的时间来探索和验证。所以,是的,我希望得到 MS Sql Server 专家的帮助,他们可能知道是否有缓存选项、事务性 v 仓库选项等可以设置,这将使世界变得不同,这将是神奇的快速按钮。

神奇的快速按钮评论可能有点居高临下。

显示索引的图片显示为我只是试图指出另一个系统似乎在被查询的列上没有索引。在这种情况下,一张图片值一千字。

4

2 回答 2

3

如果表格上写着ENGINE=MyISAM,那么这才是最重要的。在几乎所有情况下,这都是一个糟糕的选择。innodb_buffer_pool_size=16G无关紧要,只是它会从 MyISAM 中抢夺内存。

default-storage-engine=INNODB仅在创建明确指定ENGINE=.

你的一些表是 MyISAM 和一些是 InnoDB 吗?你有多少内存?

大多数性能解决方案必然涉及INDEX. 请解释为什么你买不起索引。无论表中有多少行,它都可以将该查询变成少于 10 毫秒的时间。

对不起,但我不接受“而不是在我有慢查询的地方创建索引”。

在某些情况下,将表从 MyISAM 更改为 InnoDB 将有助于提高性能。建议您在添加索引时更改引擎。

向我们展示更多查询,我们可以帮助您确定需要哪些索引。 select min(visit_start_date) from visit_occurrence;需要INDEX(date);其他查询可能不是那么微不足道。不要落入“索引每一列”的陷阱

更多的

在 MySQL...

  • 单个连接仅使用一个核心,因此只有当您拥有更多连接时,更多核心才会有所帮助。(MySQL 8.0 中存在一些微小的例外。)

  • 分区很少有助于提高性能;在没有得到建议的情况下使用它。(PS: BY RANGE也许是唯一有用的变体。)

  • 复制用于读取扩展(以及备份和...)

  • 分片用于写入缩放。它需要一堆额外的架构东西——例如将查询路由到适当的服务器。(MariaDB 有 Spider 和 FederatedX 作为可能的工具。)无论如何,分片是一项不平凡的工作。

  • 集群用于 HA(高可用性、自动故障转移等),同时帮助一些人进行读写扩展。参见:Galera,InnoDB 集群。

  • 硬件很少只是性能问题的临时解决方案。

  • 缓存会导致结果可能不一致,所以要小心。另外,请考虑我的口头禅“不要费心将缓存放在缓存前面”。

(我可以就这些主题中的任何一个提供进一步的建议。)

于 2022-02-08T21:35:36.197 回答
0

无论是在 MyISAM 还是 InnoDB 中。甚至 SQL Server,您的查询

select min(visit_start_date) from visit_occurrence;

这个索引几乎可以立即满足,因为它使用了所谓的松散索引扫描

CREATE INDEX visit_start_date ON visit_occurrence (visit_start_date);

具有像 MIN() 这样的聚合函数的查询始终是 GROUP BY 查询。但如果 SQL 语句中不存在 GROUP BY 子句,则服务器将按整个表进行分组。

您提到了使用 MyISAM 时可以立即满足的查询。那就是SELECT COUNT(*) FROM whatever_table。在幕后 MyISAM 保留表元数据,显示表中的总行数,以便查询立即返回。事务存储引擎 InnoDB 不这样做。它支持如此多的并发性,以至于它的设计者没有在他们的元数据中包含总行数,因为在很多情况下它都是错误的,不值得冒险。

索引设计不是黑色艺术。但这是一门艺术,由我们从 EXPLAIN(或 ANALYZE 或 EXPLAIN ANALYZE)获得的测量结果提供。数据库驱动的应用程序(在任何数据库服务器中)的一个基本事实是,随着应用程序的增长,需要重新访问索引。好消息:更改、添加或删除索引不会更改您的数据。

于 2022-02-10T14:56:34.610 回答