gpt4 book ai didi

php - 使用 Laravel 的长任务中的数据库过载

转载 作者:行者123 更新时间:2023-11-29 11:24:47 26 4
gpt4 key购买 nike

我目前正在努力解决数据库重载的问题,这会导致所有页面请求显着延迟。

当前情况

- A certain Artisan Command is scheduled to be ran every 8 minutes
- This command has to update a whole table with more than 30000 rows
- Every row will have a new value, which means 30000 queries will have to be executed
- For about 14 seconds the server doesn't answer due to database overload (I guess)

这里是命令handle()的handle方法

public function handle()
{
$thingies = /* Insert big query here */

foreach ($thingies as $thing)
{
$resource = Resource::find($thing->id);

if(!$resource)
{
continue;
}

$resource->update(['column' => $thing->value]);
}
}

有没有其他方法可以做到这一点而不使我的页面请求被延迟?

最佳答案

你的流程效率确实很低,而且我并不惊讶它需要很长时间才能完成。要处理 30,000 行,您需要进行 60,000 次查询(一半用于查找 id 是否存在,另一半用于更新行)。您可能只赚 1。

我没有使用 Laravel 的经验,因此我将让您自行了解 Laravel 中的哪些函数可以用来应用我的建议。我只是想让你理解这些概念。

MySQL 允许您提交多重查询;一个命令执行多个查询。它比在循环中执行单个查询要快得多。这是一个直接使用 MySQLi 的示例(没有第三方框架,例如 Laravel)

//the 30,000 new values and the record IDs they belong to. These values
// MUST be escaped or known to be safe
$values = [
['id'=>145, 'fieldName'=>'a'], ['id'=>2, 'fieldName'=>'b']...
];

// %s and %d will be replaced with column value and id to look for
$qry_template = "UPDATE myTable SET fieldName = '%s' WHERE id = %d";

$queries = [];//array of all queries to be run

foreach ($values as $row){ //build and add queries
$q = sprintf($qry_template,$row['fieldName'],$row['id']);
array_push($queries,$q);
}

//combine all into one query
$combined = implode("; ",$queries);

//execute all queries at once
$mysqli->multi_query($combined);

我会研究 Laravel 如何进行多查询并从那里开始。上次我实现类似的操作时,插入 3,000 行大约需要 7 毫秒。所以更新30000肯定不会花14秒。

还有一个额外的好处,无需首先运行查询来确定 ID 是否存在。如果没有,则不会更新任何内容。

关于php - 使用 Laravel 的长任务中的数据库过载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38417507/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com