Java MySQL性能

Java MySQL性能,java,php,mysql,lamp,Java,Php,Mysql,Lamp,我有一个LAMP应用程序,在MySQL中有大约900k行,我有一些性能问题 背景-除了LAMP堆栈之外,还有一个Java进程(多线程)在其自己的JVM中运行。因此,它们与LAMP和java一起构成了完整的解决方案。java进程负责插入/更新,很少进行选择。这些插入/更新通常是批量/批量的,在5-150行之间。PHP前端代码只执行SELECT 问题-当java进程运行时,PHP/SELECT查询变得非常慢。当java进程停止时,选择执行OK。我的意思是性能差异很大。当java进程运行时,在php前

我有一个LAMP应用程序,在MySQL中有大约900k行,我有一些性能问题

背景-除了LAMP堆栈之外,还有一个Java进程(多线程)在其自己的JVM中运行。因此,它们与LAMP和java一起构成了完整的解决方案。java进程负责插入/更新,很少进行选择。这些插入/更新通常是批量/批量的,在5-150行之间。PHP前端代码只执行SELECT

问题-当java进程运行时,PHP/SELECT查询变得非常慢。当java进程停止时,选择执行OK。我的意思是性能差异很大。当java进程运行时,在php前端执行的任何操作都会导致mysqld进程的CPU使用率增加80%

任何帮助都将不胜感激

MySQL正在使用默认参数和设置运行

软件栈-

  • Apache-2.2.x
  • MySQL-5.1.37-1ubuntu5
  • PHP-5.2.10
  • Java-1.6.0_15
  • 操作系统-Ubuntu 9.10(karmic)

您使用的MySQL引擎是什么?这里需要注意的是,如果您使用的是MyISAM,那么由于引擎使用的表锁定,您将遇到锁定问题

发件人:

表锁定也是不利的 在以下情况下:

* A session issues a SELECT that takes a long time to run.
* Another session then issues an UPDATE on the same table. This session 
  waits until the SELECT is finished.
* Another session issues another SELECT statement on the same table.
  Because UPDATE has higher priority than SELECT, this SELECT waits for the UPDATE to finish, 
  after waiting for the first SELECT to finish.
我不会在这里重复这些,但是这个页面有一些关于在MySQL中增加表的并发性的提示。显然,一种选择是改用InnoDB这样的引擎,它有一种更复杂的行锁定机制,对于高并发表,这种机制可以在性能上产生巨大的差异。有关InnoDB的更多信息,请访问。 在更改引擎之前,可能值得查看其他提示,如确保表已正确索引等,因为这将提高选择和更新性能,而不考虑存储引擎

根据用户评论进行编辑:

根据你描述的症状,我会说这是一种可能的解决方案,但可能不是 那个能让你到达你想去的地方的人。没有更多的信息是不可能说的。 由于缺少索引,您可能正在进行全表扫描。这可能会导致I/O争用 这进一步加剧了MyISAM使用的表锁。如果是这样的话 根本原因是索引和纠正不当,这将是您最好的行动方案 在更换存储引擎之前

此外,请确保您的表已规范化。这可能对性能产生深远影响 尤其是在更新方面。规范化表允许您更新一行,而不是数百行或更多行 在一个未规范化的表中有数千个。这是由于未重复的值造成的。它还可以节省大量资金 由于db可以更高效地缓存数据块,因此选择的I/O数量。在不知道结构的情况下 您正在使用的表或您提供的索引很难为您提供 更详细的答复

用户尝试使用InnoDB后编辑:

您提到您的Java进程是多线程的。您是否尝试过使用单个线程运行该进程?我想知道是否可能是您发送相同的行以更新到多个线程和/或跨线程更新的方式导致了锁定问题

除此之外,我将检查以下内容:

  • 您是否检查了explain计划以验证您的成本是否合理,以及查询是否实际使用了您拥有的索引
  • 你们的桌子正常化了吗?更具体地说,如果表被规范化,那么当您可以更新单个记录时,您是否正在更新100行
  • 当Java进程正在运行,而机器正忙于交换东西时,是否可能是物理内存不足
  • 您的磁盘(单个磁盘?)的IOPs是否超过了它可以合理处理的范围
    我们需要对系统有更多的了解,才能判断这是否正常或如何解决问题

    MySQL中大约有900k行

    我会说,这使得它非常小-所以如果它的表现不好,那么你将在某个地方严重错误

    启用查询日志以准确查看正在运行的查询,并根据频率和持续时间的乘积确定优先级。看看解释计划,创建一些索引。考虑在多个磁盘上拆分数据库


    C.

    我们是否能够查看select/db结构,以查看是否有您可能遗漏的简单内容?表结构?导致问题的insert查询的SQL是什么?运行缓慢的选择的SQL是什么?你有什么索引?是的,我正在使用MyISAM。因此,根据我的场景,建议迁移到InnoDB?让我感到困惑的是,当java进程(插入/更新)没有运行时,数据库速度非常快,java进程一启动,mysql就开始爬行。谢谢你的建议。是的,我的桌子设计相当好,它规范化了。内存也很好,磁盘io也很好。我注意到的是,有些列没有被索引,因为它们的基数很低。这些是包含值O或1的标志列。在where子句中使用这些列的查询将mysql的cpu利用率提高到60%,这意味着它们正在进行全表扫描。所以类似这样的东西-从表中选择*,其中index_flag=0,index_read_flag=1限制100。另外,我对where子句有一些计数(*),这可能也会减慢系统的速度??我在这里瞎开枪,所以这可能不是一个可行的更改,为“标记”列设置单独的表是否有意义?为了澄清这一点,如果其中一列是“活动”标志,则不需要使用带有该标志的单个表,而是创建活动表和非活动表,从而消除了对低基数布尔值的需要