使用单个查询更新多行/列(性能)

时间:2011-05-21 13:35:59

标签: php mysql

两个简单的场景:

$group_sql  = $db->prepare("UPDATE `groups` SET `group`=? WHERE `group_id`=?;");

foreach($_POST['groups'] as $id => $group)
{
    $group_sql->execute(array($group, $id));
}

多次更新:

$query      = array();

foreach($_POST['groups'] as $id => $group)
{
    $query[]    = "WHEN {$id} THEN {$db->quote($group)}";
}

$query      = "
UPDATE `groups`
SET `group` = CASE `group_id`
    " . implode("\r\n", $query) . "
END
WHERE `group_id` IN (" . implode(',', array_keys($_POST['groups'])) . ");
";

最终会产生:

UPDATE `groups`
SET `group` = CASE `group_id`
    WHEN 3054 THEN 'moteris savo vaikams'
    WHEN 3055 THEN 'bičių šeimoje'
END
WHERE `group_id` IN (3054,3055)

哪一个更好用?

更新

由于我注意到人们不熟悉这种方法,所以我决定扩展该示例以使用多列/行更新。

UPDATE `groups`
    SET `group` = CASE `group_id`
        WHEN 3054 THEN 'moteris savo vaikams'
        WHEN 3055 THEN 'bičių šeimoje'
    END,
    SET `description` = CASE `group_id`
        WHEN 3054 THEN 'foo'
        WHEN 3055 THEN 'bar'
    END
    WHERE `group_id` IN (3054,3055)

2 个答案:

答案 0 :(得分:0)

完全取决于您的表和索引结构。如果group_id是索引,以便它可以直接查找,而不扫描索引或表,则应该产生类似的性能。

如果没有编入索引,最后一个表单应该能够处理一个索引/表扫描而不是两个,这将获得更好的性能。

以这种方式处理multiupdates的有趣想法,以前没见过。

答案 1 :(得分:0)

如果你在group_id上有一个索引,那么查询计划将会是相同的:无论如何你都要对每个ID进行索引查找。如果没有,您将获得单个表扫描,而不是每个ID扫描一次。

多重查询会有轻微的性能优势,因为您可以避免往返数据库。这是否值得不使用ORM的麻烦是一个完全不同的故事。