【问题标题】:Spending time optimizing an sql query VS Pushing unnecessary data from database花时间优化 sql 查询 VS 从数据库推送不必要的数据
【发布时间】:2016-12-04 08:11:09
【问题描述】:

我的数据库中有一个相当大的表,我想要一个函数,例如,执行 UPDATE 查询。

我以前在旧项目中所做的是传递所有列的所有值,并将它们插入到查询字符串中,如下例所示:

function updateUser($id, $name, $username){

    $query =  "UPDATE user SET name = '{$name}', username = '{$username}' WHERE id = '{$id}' ";

    return mysqli_query($this->conn, $query);

} 

也就是说,每一列都被改变了,即使是那些没有改变的。

但是,这次是大表,不想牺牲应用速度。

我要做的是进行一些比较,从而优化查询,然后才将其发送到数据库。

停留在之前的 UPDATE 查询示例中,这就是我想做的事情:

function updateUser($old_user, $new_user, $user_id){

    $changed = false;

    $oldFirstName = $old_user->getFirstName();
    $newFirstName = $new_user->getFirstName();
    if($oldFirstName == $newFirstName){
        $firstNameQuery = "";
    }else{
        $firstNameQuery = " first_name = '".mysqli_escape_string($this->conn, $newFirstName)."',";
        $changed = true;
    }

    $oldLastName = $old_user->getLastName();
    $newLastName = $new_user->getLastName();
    if($oldLastName == $newLastName){
        $lastNameQuery = "";
    }else{
        $lastNameQuery = " last_name = '".mysqli_escape_string($this->conn, $newLastName)."',";
        $changed = true;
    }

    $oldEmail = $old_user->getEmail();
    $newEmail = $new_user->getEmail();
    if($oldEmail == $newEmail){
        $emailQuery = "";
    }else{
        $emailQuery = " email = '".mysqli_escape_string($this->conn, $newEmail)."',";
        $changed = true;
    }

    if($changed){
        $query = "UPDATE user SET {$firstNameQuery}{$lastNameQuery}{$emailQuery} WHERE user_id = {$user_id}";
        return mysqli_query($this->conn, $query);
    }else{
        return 0;
    }
}

尽管如您所见,随着表格的增长,该函数会变得更大,并且具有更多的比较和属性。

我的问题是:我这样做是否节省了大量时间,还是不值得?

【问题讨论】:

  • considerably big table => 需要号码请...
  • 大约 20 到 25 列...
  • DB 不关心列,行才是最重要的。顺便说一句,看看How can I prevent SQL injection in PHP?,因为你的代码不安全
  • 哦,我明白了。谢谢。在安全问题上,我认为mysqli_escape_string() 负责 SQL 注入,不是吗?
  • 当你读取一行时,你会得到所有的 col,这对数据库来说很容易,因为数据通常在驱动器上接近/在一起。当您必须读取每一行的非索引 col 时会发生不好的想法,因为 DB 必须读取并跳转到驱动器上的整个 db 文件中。对于注射,我没有看到您的 mysqli_escape_string() ,所以是的,它是安全的,但是如果可以的话,请使用准备好的声明,因为您将所有安全性放在一条线上并且只需要牢记“永远不要在我的查询中添加$var"

标签: php mysql sql optimization


【解决方案1】:

您可能正在使代码降低效率。更新的大部分时间是记录事务和物理存储每条记录的数据页。因为单个记录的所有列(通常)都存储在一个页面上,所以更新一列或多列并不重要。

另一方面,应用程序中的额外比较也需要时间。

当然 - 与任何与性能相关的问题一样 - 您可以测试不同的场景。我不希望通过这样的逻辑来减少更新中的列数来显着提高性能,除非它完全消除了更新某些行的需要。

【讨论】:

  • 我明白了。但在其他情况下,例如选择或插入,是否适用相同的逻辑?
  • @MatheusAlmeida 一行读取或写入在整行上,如果您关心性能,请查看如何在WHERE 中使用的字段上使用 INDEX,并避免存储大数据(像原始图片)在数据库中,或者至少将它们保存在一个专用表上,您只在需要时才查询
猜你喜欢
  • 2015-01-18
  • 1970-01-01
  • 1970-01-01
  • 2011-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多