我们的服务器用MariaDB从Ubuntu16升级到Ubuntu20.不幸的是,网站的加载时间变慢了.通常情况下,MariaDB应该比Mysql更快.我发现,很简单,网站上的更新命令有时需要7秒钟.但是,如果我通过myphpadmin将这些更新命令直接输入数据库,它们只需要0.0005ms.

在我看来,当更新命令频繁出现时,MariaDB似乎有问题.mysql从来都不是问题.下面是一个查询示例:

UPDATE LOW_PRIORITY users
SET user_video_count = user_video_count + 1
WHERE user_id = 12345

数据库格式是MyISAM.

我不知道原因是什么.你…吗?

非常感谢你.

推荐答案

它可能像SELECTusers中搜索一样简单.Note,InnoDB不会遇到这个问题.

MyISAM在做UPDATEINSERTDELETE时必然做table lock.(还有ALTER和其他DDL语句.)如果有很多连接同时进行写操作,甚至是SELECTs次,那么锁可以级联很长时间.

真正的解决方案,无论是在MariaDB中还是在MySQL中,都是切换到InnoDB.

如果这是"喜欢"或"视图"的大量计数,那么部分解决方案(在任一引擎中)是将此类计数器放在一个单独的并行表中.这避免了那些简单而快速的更新与主表上的其他操作发生冲突.在交通量极高的地区,收集此类增量并批量应用是必要的.我认为你的书不需要那种激进的解决方案.

MySQL几乎已经淘汰了MyISAM.马里亚布可能会在几年后效仿.

为了解决这个问题:

在同一个phpadmin查询中

问题不在于如何运行它,而在于同时发生了什么.

(LOW PRIORITY是MyISAM特有的乱七八糟的说法,有时会奏效.)

MyISAM做"表锁定";InnoDB执行"行锁定".因此,Innodb可以在一个表上执行很多"同时"操作,而MyISAM在一次写操作发生时就会被序列化.

More(现在专注于InnoDB.)

可能涉及的其他一些事情.

如果两个UPDATEs同时试图修改same row,一个将不得不等待(由于行锁定).

如果真的有大量的事情发生,延迟可能会层出不穷.如果在一个实例中有20个连接正在积极运行,那么它们都会相互减慢速度.每个连接都有一个公平的份额,但这意味着它们的速度都变慢了.

SHOW PROCESSLIST来查看运行的是什么,而不是"睡眠"."时间"最高的进程(系统线程除外)很可能是引发争吵的原因.

慢波可以帮助潜水更深.我打开它,以足够低的long_query_time,等待"事件"发生.然后我用pt-query-digest(或mydumpslow -s t)找出最慢的查询.再努力一点,你可能会注意到有很多查询在一瞬间"很慢"——甚至可能是"点查询"(比如UPDATE ... WHERE id=constant)出乎意料地运行得比long_query_time慢.这表示查询太多和/或某些查询意外锁定了行.(注意:查询的"时间戳"是在查询ended时,减go Query_time即可开始.)SlowLog

More

正如您所发现的,当快速执行大量单查询事务时,innodb_flush_log_at_trx_commit = 2是一个很好的解决方案.如果频率变得太大,无法修复,那么我上面的 comments 可能是必要的.

=2和=0之间不会有太大的性能差异.

至于innodb_flush_log_at_timeout.请提供"显示全局状态,如"Binlog%committes"

至于innodb_lock_wait_timeout...我认为改变这一点对你没有帮助.如果您的一个查询由于超时而中止,您应该记录它的发生并重试事务.

听起来你是在运行autocommit = ON个,而不是使用显式事务?这很好(对于非金钱活动).在某些情况下,使用事务有助于提高性能,例如人为地将多个查询批处理在一起以避免某些I/O.缺点是与其他连接冲突的可能性增加.尽管如此,如果你总是判断错误并重新运行"事务",一切都应该很好.

innodb_flush_log_at_trx_commit

当该设置为"1"(可能是您最初的设置)时,每次更新都会额外写入磁盘以确保数据完整性.如果磁盘是HDD(不是SDD),那么每次更新都会增加大约10毫秒,因此每秒最多会有大约100次更新.有几种方法可以解决这个问题.

  • innodb_flush_log_at_trx_commit = 0 or 2,牺牲了一些数据完整性.
  • 人为地将几个更新组合到一个事务中,从而将10毫秒的时间分散到多个查询中.
  • 根据他们正在做的事情和/或他们接触的行,显式地组合多个更新.(在非常繁忙的系统中,这可能涉及其他服务器和/或其他表.)
  • 将计数器移动到另一个表(见上文)——这允许主表上更耗时的操作产生干扰.(我没有听到一个明确的例子,但slowlog可能已经指出了这一点.)
  • 切换到SSD驱动器——更新容量可能会增加10倍.

我怀疑社交媒体巨头会做上述所有事情.

Mysql相关问答推荐

为什么我的带有索引字段和非索引字段的 Select 有时需要很长时间

含有子查询的MySQL函数出现语法错误

MySQL中如何对字符串进行算术运算?

使用Workbench时如何添加mysqldump配置标志

特定时间段内每个客户的运行总计

在 MySQL 中,如何对 LIKE 查询进行批量更新,删除字符?

即使在某些表中不匹配,如何从 MySQL 中的多个表中 Select 所有记录

SQL从字典中的键获取值

Laravel 查询构建器 where() 用于何时产品必须有多个标签(使用 product_tags 数据透视表多对多)

限制正则​​表达式中多字符通配符的范围

如何查看 rdsadmin 在 mysql 实例上的权限?

SQL UPDATE中的str_replace?

MySQL:使用来自查询的信息创建一个新表

在 MySQL 中,我应该 Select 哪种排序规则?

何时在 mysql 中使用 TEXT 而不是 VARCHAR

mysqli_fetch_array() 期望参数 1 为 mysqli_result,布尔值

如何使用 SQL 数据库中的经纬度查找最近的位置?

在另一个 where 语句(子查询?)中使用一个 sql 查询的结果

MySQL 连接运算符

为什么在 MySQL 中使用外键约束?