我正在尝试更新数据库中的~100000行,我运行的查询如下:
UPDATE urlpool
SET selfcrawlestate = 0
WHERE urlpool.url LIKE '%gr.example%' AND urlpool.url NOT IN
(SELECT crawledurl
FROM userscrawled
WHERE userscrawled.crawledurl LIKE '%gr.example%')
LIMIT 400
上面的代码工作了2-3次(并更新了值),但现在当我运行它时,它返回一个“0行受影响”的消息。
当我运行另一个查询来检查是否还有要更新的行时,它会再次返回~100000行。
SELECT *
FROM urlpool
WHERE urlpool.url LIKE '%gr.example%' AND urlpool.url NOT IN
(SELECT crawledurl
FROM userscrawled
WHERE userscrawled.crawledurl LIKE '%gr.example%')
你知道我在这里做错了什么吗?
答案 0 :(得分:4)
LIMIT
子句是"匹配的行#34;限制。当找到指定的行数时,查询将停止,无论这些行是否更新。
一种可能的解决方法是在UPDATE中包含谓词,以便不需要更新不需要更新的行,例如
WHERE ...
AND NOT ( selfcrawlestate <=> 0 )
LIMIT 400
您可以在查询中包含相同的谓词,以检查应更新的行数。
请注意,MySQL不会增加受影响的&#34;行#34;由于selfcrawlestate列的值已设置为0,因此不需要更新的行的计数器。
<强>后续强>
MySQL特定的 <=>
运算符是一个空安全的等式比较器。它认为NULL值对于比较有效,并保证返回TRUE或FALSE。 (这与常规等式比较器 =
不同,如果要比较的任一操作数为NULL,它将返回NULL
。(SQL布尔值可以具有以下三个值之一: TRUE,FALSE或NULL)。
布尔表达式:
NOT ( foo <=> 0 )
相当于:
( foo IS NULL OR foo <> 0 )
答案 1 :(得分:2)
您将更新限制为LIMIT 400
的400行。每次调用UPDATE时都会更新相同的行,因为它们已经更新,所以会得到0 rows affected
。如果删除限制,则将更新所有~100000行。
如果您必须小批量更新,请添加一些条件以确保每次调用都会更新新记录 - 例如 - AND selfcrawlestate > 0
。