如何提高 MySQL INSERT 和 UPDATE 性能?

mma*_*tax 15 mysql performance innodb

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

我们数据库中 INSERT 和 UPDATE 语句的性能似乎正在降低并导致我们的 Web 应用程序性能不佳。

表是 InnoDB 并且应用程序使用事务。是否有任何简单的调整可以加快速度?

我想我们可能会看到一些锁定问题,我怎样才能找到?

sum*_*mar 25

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

    • 问题来源(CPU/IO/内存/交换使用)。你有很多IOP吗?CPU 负载了吗?如果您有大量读取 IOP,则可能没有足够大的 InnoDB buffer_pool。如果 CPU 已加载,您的查询可能会执行全表扫描,而不是使用正确的索引。
    • 磁盘/RAID/LVM 设置。在某些特定设置中,LVM 条带化可以通过均衡磁盘负载(无硬件 RAID,连接多个 LUN)给您带来好处
    • 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 天!!!分析slowquery log后发现,这种类型的更新查询需要4秒才能完成。查询是这样的: update table1 set field1=value1 where table1.field2=xx table2.field3=yy and table2.field4=zz。在将更新查询转换为选择查询并在该选择查询上运行解释后,我们发现这种类型的查询不使用索引。创建适当的索引后,我们将更新查询的执行时间减少到几毫秒,整个工作在不到两个小时的时间内完成。

一些有用的链接:


小智 5

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

如果您可以处理丢失 1s 的事务,这可能是极大提高写入性能的好方法。

另外,请注意您的磁盘在做什么。RAID 10 > RAID 5 用于以额外磁盘为代价的写入。


War*_*ner 1

锁定问题将通过以下连接状态来举例说明show full processlist;

通读my.cnf和 MySQL 文档。配置选项有很好的文档记录。

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

调整将针对您首选的数据库引擎和应用程序架构。通过互联网搜索就可以找到大量资源。