MySQL 设置 JOIN ON 字段是否有效? "JOIN ON a = b SET a = c"
MySQL Setting a JOIN ON field valid or not? "JOIN ON a = b SET a = c"
我可以更新用于联接的同一列吗?好像可以,但是当我这样做时我的脚本崩溃了。
背景:我有一个正在迁移的旧数据库。我正在通过 PHP 循环中的大量 MySQL 查询 运行 来处理它。循环工作得很好,每个查询需要 0.5 到 1 MB 的内存来处理。直到它遇到这个查询,突然它占用了我分配给 PHP:
的任何内存的 101%
UPDATE a.t1
INNER JOIN t2
ON t1.category = t2.oldcategory
SET t1.category = t2.newcategory
WHERE t1.category <> '';
当 memory_limit 设置为 128M 时抛出的错误是:
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted
(tried to allocate 12288 bytes)
当我将 memory_limit 增加到 256M 时,错误是:
PHP Fatal error: Allowed memory size of 268435456 bytes exhausted
(tried to allocate 32768 bytes)
但是这个非常相似的查询运行得很好:
UPDATE a.t1
INNER JOIN t2
ON t1.category = t2.oldcategory
SET t1.series = t2.series_term
WHERE t1.category <> '' AND t2.newcategory <> '';
PHP 请求代码:
$queries = array (
// dozens of MySQL queries here, like this:
["Count users",
"SELECT id from $s2.$usr;"
],
)
foreach ($queries as $query){
$mtime = time();
$result = mysqli_query($link, $query[1]);
$mem = number_format((memory_get_usage()/1024/10124),2);
$mtime = time() - $mtime;
$mtime = gmdate("i:s", $mtime);
if ($result) {
$rows = number_format(mysqli_affected_rows($link));
echo "<tr><td>$mtime</td><td>$rows</td><td>$query[0] — $mem Mb</td></tr>";
} else {
$rows = mysqli_error($link);
echo "<tr><td>X</td><td>X</td><td>".$query[0]."<br><span style='color:red;'>".$rows."</span></td></tr>";
}
}
在用于 ON
的同一列上使用 SET
是否存在非法或递归问题?
更新:
我刚创建了两个小测试表并成功运行这个查询:
# works
UPDATE table1 t1
JOIN table2 t2
ON t1.column1 = t2.column1
SET t1.column1 = t2.column2
WHERE t1.column1 <> '';
更新 2:
我编辑了 WHERE 子句,现在它使用 0.04 Mb 的内存在 0.19 秒内正确运行:
UPDATE a.t1
INNER JOIN t2
ON t1.category = t2.oldcategory
SET t1.category = t2.newcategory
WHERE t1.category <> '' AND t1.category <> t2.newcategory;
我认为下面的代码也能正常工作!
**这里代码:**
更新 a.t1
内连接 t2
ON t1.category = t2.oldcategory
# SET t1.series = t2.series_term ## 没有 SET
其中 t1.category '' 和 t2.newcategory '';
**AND t2.newcategory ''** 条件越多越有效。
我认为更多的条件让它工作,因为更多的条件过滤更多的数据并让 MySQL 使用更少的内存。
抱歉,刚看了你的代码,你不能在连接条件上设置数据,你会死循环
不可以t update same columns which are used in join statement.
Think about the logic.
It updates one row and it has to recheck the value again since it
使用同一列加入。所以这变成了无限递归,这将导致内存不足异常。
为什么不先把需要更新的ids和values保存在键值数组中。
然后运行一个循环,分别更新?
SELECT t1.id,t2.newcategory from t1
INNER JOIN t2
ON t1.category = t2.oldcategory
运行 结果列表的 foreach
循环并更新每一行
foreach($queryResul as $row){
UPDATE t1 SET t1.category = $row->newcategory where t1.id = $row->id; }
我可以更新用于联接的同一列吗?好像可以,但是当我这样做时我的脚本崩溃了。
背景:我有一个正在迁移的旧数据库。我正在通过 PHP 循环中的大量 MySQL 查询 运行 来处理它。循环工作得很好,每个查询需要 0.5 到 1 MB 的内存来处理。直到它遇到这个查询,突然它占用了我分配给 PHP:
的任何内存的 101%UPDATE a.t1
INNER JOIN t2
ON t1.category = t2.oldcategory
SET t1.category = t2.newcategory
WHERE t1.category <> '';
当 memory_limit 设置为 128M 时抛出的错误是:
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted
(tried to allocate 12288 bytes)
当我将 memory_limit 增加到 256M 时,错误是:
PHP Fatal error: Allowed memory size of 268435456 bytes exhausted
(tried to allocate 32768 bytes)
但是这个非常相似的查询运行得很好:
UPDATE a.t1
INNER JOIN t2
ON t1.category = t2.oldcategory
SET t1.series = t2.series_term
WHERE t1.category <> '' AND t2.newcategory <> '';
PHP 请求代码:
$queries = array (
// dozens of MySQL queries here, like this:
["Count users",
"SELECT id from $s2.$usr;"
],
)
foreach ($queries as $query){
$mtime = time();
$result = mysqli_query($link, $query[1]);
$mem = number_format((memory_get_usage()/1024/10124),2);
$mtime = time() - $mtime;
$mtime = gmdate("i:s", $mtime);
if ($result) {
$rows = number_format(mysqli_affected_rows($link));
echo "<tr><td>$mtime</td><td>$rows</td><td>$query[0] — $mem Mb</td></tr>";
} else {
$rows = mysqli_error($link);
echo "<tr><td>X</td><td>X</td><td>".$query[0]."<br><span style='color:red;'>".$rows."</span></td></tr>";
}
}
在用于 ON
的同一列上使用 SET
是否存在非法或递归问题?
更新:
我刚创建了两个小测试表并成功运行这个查询:
# works
UPDATE table1 t1
JOIN table2 t2
ON t1.column1 = t2.column1
SET t1.column1 = t2.column2
WHERE t1.column1 <> '';
更新 2:
我编辑了 WHERE 子句,现在它使用 0.04 Mb 的内存在 0.19 秒内正确运行:
UPDATE a.t1
INNER JOIN t2
ON t1.category = t2.oldcategory
SET t1.category = t2.newcategory
WHERE t1.category <> '' AND t1.category <> t2.newcategory;
抱歉,刚看了你的代码,你不能在连接条件上设置数据,你会死循环
不可以t update same columns which are used in join statement.
Think about the logic.
It updates one row and it has to recheck the value again since it
使用同一列加入。所以这变成了无限递归,这将导致内存不足异常。
为什么不先把需要更新的ids和values保存在键值数组中。 然后运行一个循环,分别更新?
SELECT t1.id,t2.newcategory from t1
INNER JOIN t2
ON t1.category = t2.oldcategory
运行 结果列表的 foreach
循环并更新每一行
foreach($queryResul as $row){
UPDATE t1 SET t1.category = $row->newcategory where t1.id = $row->id; }