何时对给定连接的慢速 MySQL 查询会影响其他连接



我想我对此有基本的了解,但我希望有人能给我更多细节,因为我有兴趣了解更多关于数据库性能的信息。

假设我有一个非常大的数据库,有数百万个条目,该数据库支持许多连接。 对数据库执行简单的查询会很慢,因为数据太多了。 我试图准确了解给定连接上的查询何时开始对在其他连接上运行的查询的性能产生直接影响。

如果一个连接锁定了一些元素,我知道这将阻止运行需要这些元素的其他连接的查询。 例如,执行:

SELECT FOR UPDATE

将锁定您选择的内容。

当您执行以下简单操作时会发生什么:

SELECT COUNT(*) FROM myTable

假设我们有一个包含十亿行的表,因此运行计数将花费一些时间(在 InnoDB 上运行)。 它是否会影响在其他连接上运行的查询?

如果使用 SELECT 和 JOIN 选择大量数据,例如:

SELECT * FROM myTable1 JOIN myTable2 ON myTable1.id = myTable2.id;

让联接锁定其他查询有什么好处吗?

我发现很难知道哪些查询会对在其他连接上运行的查询的性能产生直接影响。

谢谢

有不同的角度:

  • 行锁定:如果您调整架构,这不应该发生,所以您应该忘记它
  • 实际性能问题和瓶颈。在我们的例子中,附带效应。

关于这第二点,问题主要分为3个方面:

  • 磁盘读取
  • 内存使用情况(缓冲区)
  • CPU 使用率。

关于磁盘读取:您将检索的数据(以字节为单位)越多,硬盘驱动器就越忙,并减慢使用它的任何其他活动。减小所选行的大小以避免磁盘开销。

关于内存使用情况:mysql 管理一个内部缓冲区,在某些情况下可能会卡住。我对它的了解还不够多,无法给你一个正确的答案,但我知道这绝对是你应该关注的事情。

关于CPU的使用:基本上CPU在它的时候会变得很忙

  • 必须计算(连接,准备语句,算术...
  • 必须做所有外围的事情:例如将字节从磁盘移动到内存。优化查询以减少 CPU 开销。(听起来很傻,但无论如何,它总是被证明是问题所在......

那么,现在什么时候知道什么时候会有附带效应呢?通过分析您的硬件...如何剖析?

  • 绝对分析:使用 SHOW INNODB STATUSSHOW PROFILE 获取有关主 MySQL 硬盘驱动器、CPU 和内存监视的有用信息。
  • 相对分析:使用您喜欢的操作系统探查器。例如,在Windows xp下,您可以使用出色的perfmon.exe并监视mysql进程的PRIVATE BYTESVIRTUAL BYTES。我说相对的,因为毕竟如果查询在您的计算机上很耗时,那么它可能不在 NASA 系统上......

希望它有帮助,问候。

这是一个非常普遍的问题,因此很难给出准确的答案。

您可以将数据库视为共享资源池;特别是因为运行数据库的基础硬件具有物理限制。 大多数情况下,您看到诸如选择查询之类的内容会对其他查询造成性能影响的原因是因为它们都在竞争使用这些底层物理资源,例如磁盘 IO 或 RAM 访问或 CPU 时间,并且没有足够的资源可以绕过。

因此,您看到的实际结果在很大程度上取决于数据库的物理硬件和配置设置。

例如,在您的选择示例中,变量可能是:查询所需的数据是否已在 RAM 中? 它能否通过索引有效地查找行? 如果它确实必须执行 IO,有多少其他查询要求从磁盘读取数据? 您是否正在使用二级索引并且必须执行多次读取? 数据库是否正在执行预读以缓冲其他页面? 查询是导致顺序还是随机 io? 是否有任何更新锁定数据? 物理硬件可以支持多少读取 IO?

您必须回答当前执行的所有查询的所有这些问题,以了解它们是否会影响其他查询的性能。

这就是DBA存在的原因。 繁忙的数据库是一个复杂的系统,它都是关于许多不同操作的交互,所有这些操作都有数千个可能的变量影响它们。

因此,您

通常要做的是优化您可以控制的内容以及您知道如何控制的东西(硬件,mysql配置,模式和索引),然后在系统运行时开始测量系统以了解实际发生的事情。

因此,在您的情况下,我会说专注于单独优化查询会更有帮助。 他们执行得越快,他们可能使用的资源就越少,他们对他人的影响就越小。 然后你学会分析系统。 只要看看一件很慢的事情,然后问"为什么这么慢? 然后修复它。 这就是优化过程。

但是,在第一种情况下,您使用 SELECT 编写...对于更新,显式锁定可能并且将会是很大的性能问题。 小心这些。

读取查询仅受其他查询的隔离级别影响。他们自己永远不会挡住桌子。

隔离级别是指定的事务安全模式。如果使用锁定的另一个查询不允许脏读,则您的读取将被保留,直到另一个查询完成写入或解锁。

MVCC 是一种机制,允许数据库在需要更新或删除时创建数据的新版本。这意味着当您开始读取当前版本的数据时,它的数据不会被未来的更新/删除所污染。

当您开始写入当前数据时,尽管数据当前正由另一个进程读取,您实际上是在其他地方写入新内容并将它们标记为最新版本。这最终意味着不会阻塞写入过程(至少不是因为阅读过程)。

最新更新