Php 当多个选择正在进行或花费太多时间时,Mysql无法更新行

Php 当多个选择正在进行或花费太多时间时,Mysql无法更新行,php,mysql,Php,Mysql,我有一个名为Settings的表,它只有一行。这些设置对于我的程序来说非常重要,每秒有200到300个用户读取这些设置。我还没有使用任何缓存。我无法更新设置表中的限制值。将限制从5-10更改为API中的任何内容。 例:限制产品5-10。更新查询将永远运行。 从工作台,我可以更新记录,但从管理面板通过API,它不会更新或需要太多时间。表-InnoDB 1. Already Tried Locking With Read - Write. 2. Transaction. 3. Made a Vie

我有一个名为Settings的表,它只有一行。这些设置对于我的程序来说非常重要,每秒有200到300个用户读取这些设置。我还没有使用任何缓存。我无法更新设置表中的限制值。将限制从5-10更改为API中的任何内容。 例:限制产品5-10。更新查询将永远运行。 从工作台,我可以更新记录,但从管理面板通过API,它不会更新或需要太多时间。表-InnoDB

1. Already Tried Locking With Read - Write. 
2. Transaction.
3. Made a View of the table and Tried to update the table, the Same Issue remains.
4. The Update query is fine from Workbench, But through an API. It runs all day.
无论如何,我可以锁定表上的读取操作并更新表。我一张桌子只有一排


任何帮助都将不胜感激,提前感谢。

这听起来是一个非常好的使用案例

查询缓存存储SELECT语句的文本以及发送到客户端的相应结果。如果稍后收到相同的语句,服务器将从查询缓存中检索结果,而不是再次解析和执行该语句。查询缓存在会话之间共享,因此可以发送一个客户端生成的结果集来响应另一个客户端发出的相同查询

查询缓存在具有不经常更改的表并且服务器接收到许多相同查询的环境中非常有用

要启用查询缓存,可以运行:

SET GLOBAL query_cache_size = 1000000;
然后编辑mysql配置文件(通常为/etc/my.cnf或/etc/mysql/my.cnf):

然后,您可以将查询更改为:

SELECT SQL_CACHE * FROM your_table;
这将使您能够更新表(因为它不会一直被锁定)

您需要重新启动服务器

作为替代方案,您可以在PHP应用程序中实现缓存。我会使用memcached,但作为一个非常简单的解决方案,您可以执行以下操作:

$settings = json_decode(file_get_contents("/path/to/settings.json"), true);
$minute = intval(date('i'));
if (isset($settings['minute']) && $settings['minute'] !== $minute) {
    $settings = get_settings_from_mysql();
    $settings['minute'] = intval(date('i'));
    file_put_contents("/path/to/settings.json", json_encode($settings), LOCK_EX);
}

查询是在事务上下文中运行的,比如说具有事务隔离级别的可重复读取吗?由于表被锁定,更新似乎无法完成,在这种情况下,缓存可能无法帮助您,因为在写操作中,缓存将被清除。有关可重复读取的更多信息,请访问。

尚未尝试缓存结果,需要超级特权才能运行查询,我将尝试实现并尽快返回@daveHI@dave,我是否需要重新启动服务器以启用查询缓存,因为用户已经在与应用程序交互。我已经按照谷歌控制台上的建议进行了配置,无法注意到任何差异,我是否遗漏了什么。请回复。嗨@dave,我已经通过将结果缓存到memcached中实现了这一点。我能够更新表并覆盖memcahed中的数据。非常感谢。他不会写,因为一个表可以同时有多个读锁。因为他每秒有200-300个用户,所以读取锁永远不会被释放。我不清楚为什么缓存在这里没有帮助-缓存意味着表通常不会被锁定,因此他可以进行写操作,在写操作时,缓存将被清除,因此客户端将获得新值,然后重新创建缓存,再次防止表被锁定。或者我遗漏了什么?老实说,这归结为数据库中缓存的实现细节,我对MySQL还不太了解,无法回答。这是我试图避免的类型,应用程序只有在使用缓存时才能工作,即使它确实工作。回顾最初的问题,“4.更新查询在Workbench中很好,但通过API运行。它整天都在运行。”这一事实似乎向我表明,这不是一个固有的锁,而是通过API进行读写的上下文导致了问题,这就是我为什么要问事务隔离级别的原因。@Erik Brandsberg,非常感谢您对我的帮助。我已经尝试了以上所有方法,包括Dave关于缓存的建议。正如您所说,可能存在通过API调用的读写锁。即使选择更新也需要很多时间。让我浏览一下链接,找出处理这种情况的方法,因为这个表只有一行,并且被锁定,这会导致更新进程延迟。我有一个相当简单的方法来调试它——你能通过erik(at)heimdalldata.com与我联系吗?它将使用我开发的产品,但我保证这只是为了帮助调试您的问题,而不是推销。嗨@Erik Brandsberg,我不知道缓存方法。我通过在memcached中缓存结果来实现这一点。我能够更新表并覆盖memcahed中的数据。我一定会打你的。非常感谢你。
$settings = json_decode(file_get_contents("/path/to/settings.json"), true);
$minute = intval(date('i'));
if (isset($settings['minute']) && $settings['minute'] !== $minute) {
    $settings = get_settings_from_mysql();
    $settings['minute'] = intval(date('i'));
    file_put_contents("/path/to/settings.json", json_encode($settings), LOCK_EX);
}