如何提高MySQL INSERT和UPDATE性能?


14

也可以在StackOverflow上问这个问题,但我会先在这里尝试...

数据库中INSERT和UPDATE语句的性能似乎正在下降,并导致Web应用程序的性能下降。

表是InnoDB,应用程序使用事务。我可以做些简单的调整来加快速度吗?

我认为我们可能会遇到一些锁定问题,如何找到?


最好在dba.stackexchange.com
Pacerier

Answers:


25
  1. 检查您的硬件和操作系统是否已正确配置和调整:

    • 问题根源(CPU / IO /内存/交换使用)。您有很多IOP吗?是否装有CPU?如果您有很多读取的IOP,可能您没有足够大的InnoDB buffer_pool。如果加载了CPU,则您的查询可能会执行全表扫描,而不是使用适当的索引。
    • 磁盘/ RAID / LVM设置。在某些特定设置中,LVM条带化可以通过均衡磁盘负载(未连接硬件RAID,多个LUNS)使您受益。
    • IO调度程序:当您拥有良好的硬件RAID控制器时,noop最好。RedHat进行了一些测试,他们说,对于Oracle(和其他DB)而言,CFQ是最佳选择。您需要运行一些基准测试(例如tpc-c或tpc-e),然后选择最适合您的硬件的基准。
    • 好的文件系统-ext3在特定于数据库的工作负载中表现不佳。XFS或OCFS2更好。您再次需要一些基准。
    • 注意,如果您的系统使用交换。使用交换会降低mysql的性能
  2. 检查您的MySQL / InnoDB实例是否正确调整:

    • 缓冲池大小-在内存中缓存数据页
    • innodb_flush_method = O_DIRECT-避免双重IO缓冲
    • 增加InnoDB日志文件的大小-对于写入密集型工作负载,这可以提高性能。但是请记住:更大的日志文件意味着更长的崩溃恢复时间。有时几个小时!
    • innodb_flush_log_at_trx_commit = 0或2-如果您不关心ACID,并且可以在最近一两秒内放弃事务。
    • key_buffer_size-对MyISAM非常重要,但是它用于磁盘临时表。
    • 观看您的INNODB状态
  3. 分析您的工作量-捕获所有查询到慢速查询日志并在其上运行mk-query-digest。您可以使用tcpdump和maatkit捕获所有查询
    • 哪些查询会占用您的大部分服务器时间?
    • 是否创建了任何临时表,特别是大的临时表?
    • 学习,使用方法讲解
    • 您的应用程序使用交易吗?当您使用autocommit = 1(默认为MySQL)运行查询时,每个插入/更新查询都会开始新的事务,这会产生一些开销。如果可能的话,最好禁用自动提交(在python MySQL驱动程序中默认禁用自动提交),并在完成所有修改后手动执行提交。
    • 您的应用程序是否在循环中对同一张表进行一系列插入?Load data infile对于一系列插入,命令要快得多。
    • 请记住:select count(*) from table;对于innodb而言,它比对myisam而言要慢得多。
    • 哪种类型的INSERT / UPDATE查询占用服务器大部分时间?如何优化它们?
    • 检查您的数据库是否具有正确的索引,并在需要时添加它们。

在我们的环境中,有一种情况,一种更新查询速度很慢。估计完成批处理时间为2天!!!在分析了慢查询日志后,我们发现这种类型的更新查询需要4秒钟才能完成。查询看起来像这样: update table1 set field1=value1 where table1.field2=xx table2.field3=yy and table2.field4=zz。在将更新查询转换为选择查询并运行说明之后,我们发现该查询不使用索引。创建适当的索引后,我们将更新查询的执行时间缩短到了几毫秒,并且整个工作在不到两个小时的时间内完成了。

一些有用的链接:


在所有这些检查索引之前。像“随着表变大,因为我们没有索引”而使SMELL降级。
TomTom

5

使用默认的innoDB配置,您将被限制为可以将事务写入和刷新到磁盘的速度。如果您可以处理一点ACID,请尝试使用innodb_flush_log_at_trx_commit。设置为0大约每秒写入一次日志并将其刷新到磁盘。设置为1(默认)可在每次提交时写入并刷新。设置为2可在每次提交后写入日志文件,但每秒仅刷新一次。

如果您可以处理交易失败的情况,那么这可能是极大提高写入性能的好方法。

另外,请注意磁盘的功能。RAID 10> RAID 5用于写入,但需要额外的磁盘。


1

锁定问题将以中的连接状态为例 show full processlist;

通读my.cnf和MySQL文档。有关配置选项的文档非常详尽。

一般来说,您希望在内存中尽可能多地进行处理。对于查询优化,这意味着避免使用临时表。正确应用索引。

调整将特定于您首选的数据库引擎和应用程序体系结构。互联网搜索已经存在大量资源。



0

InnoDB是一个非常不错的引擎。但是,它高度依赖于“调整”。一件事是,如果您的插入不是按增加主键的顺序进行,则innoDB所花的时间可能比MyISAM长。可以通过设置更高的innodb_buffer_pool_size来轻松克服。我的建议是将其设置为总RAM的60-70%。我现在正在生产中运行4台这样的服务器,每分钟插入约350万行。他们已经有将近3 TB的数据。InnoDB由于必须高度并发插入,因此必须为InnoDB。还有其他加快插入的方法。我已经对一些基准进行了基准测试。


0

我如何通过仅在Java中禁用一次自动提交和提交更改来解决Web应用程序中MySQL中插入和更新性能的问题。如mysql文档中所建议。

MySQL文档

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.