这样的问题我已经遇到过无数次了,我总是觉得这不是最有效的逻辑,我似乎找不到一个直接的答案:
如果需要基于某些条件检查数据库,并在匹配为真时更新记录,而如果匹配为假,则转到不同的语句,最后,如果所有数据库匹配都返回假,则插入新记录,是否有更有效的方法来优化当前分支?
$id = *first query to look for id* //returns null if no match
if (is_null($_id)) { #no match
$id = *fallback query looking for id *; -->returns null if no match
}
if (is_null($id)) {#still no match
$id = *last fallback query looking for id*; -->returns null if no match
}
if (is_null($id)) { # no match was found, doesn't exist in DB so insert it
//code to INSERT the new record
} else { #match was found
//code to update the record*
}发布于 2015-04-26 11:14:00
你有没有研究过使用REPLACE INTO?
http://www.mysqltutorial.org/mysql-replace.aspx
发布于 2015-04-26 11:29:37
最有效的方法是运行一条MySQL语句...
INSERT ... ON DUPLICATE KEY UPDATE 这种方法可能不适合您的用例,但是消除检查行是否存在的查询可以提高性能。只要尝试插入行,如果它违反了唯一键约束,MySQL将拒绝它,不需要使用单独的SELECT语句进行检查。如果插入行的尝试引发"duplicate key“异常,则执行UPDATE部分中指定的赋值。
这种方法要求表至少有一个唯一约束,而不是AUTO_INCREMENT或系统分配的代理键。同样,您的用例可能不满足此要求,因此此方法可能不适合。
另一个注意:使用问题中概述的方法,并发系统中存在竞争条件的可能性。客户端运行SELECT来查找行,如果未找到行,则运行后续的INSERT。第二个会话也可以查找相同的行,但找不到它,并尝试插入它。
问题是数据库操作“检查行,如果行不存在则插入”不是原子的,因为有多次往返。
db session 1 - check if row exists, not found
db session 2 - check if row exists, not found
db session 1 - insert the row - succeed
db session 2 - insert the row - FAIL - because row already inserted如果我们坚持运行单独的SELECT来查找是否存在“匹配”行的方法,那么我们至少可以尝试通过组合在单个语句中查找匹配行的查询来避免多次往返来定位该行;我们应该至少能够获得两个单独的SELECT语句,并结合UNION ALL,并且我们可以返回一个鉴别器列来区分哪个查询返回了一行。
https://stackoverflow.com/questions/29873218
复制相似问题