1

这是我用来访问数据库的函数,理论上可能在一个 do while 循环中上升 10-20 次,尽管现在我删除了循环,所以它一次只能执行一个数据库查询。这是否可以进一步优化,或者这是如何正确完成事务和提交?另外,我不知道 $db->rollBack() 实际上做了什么,我只是在 stackoverflow 上看到的

<?php
  function util_db_access($statement, $array) {
    $db = new PDO('mysql:host=localhost;dbname=db;charset=UTF8', 'user', 'pass');

    try {
      //echo "1";
      $db->beginTransaction();
      //echo "2";
      $stmt = $db->prepare($statement);
      //echo "3"; 
      if($stmt->execute($array)) {
        $db->commit();
        //echo "4";
        if($rows = $stmt->fetchAll(PDO::FETCH_ASSOC)) {
          //echo "5";
          if($stmt->rowCount() < 2) {
            $rows = $rows[0]; 
          }
          return $rows;
        } else {
          //echo "6.1";
          //$db->commit();
          return true;
        }
      } else {
        //echo "6.2";
        //$db->commit();
        return false;
      }
    } catch(PDOException $e) {
      $db->rollBack();
      //log, we are gonna keep a log eventually.. right?
      return -1;
    }
  }
?>
4

4 回答 4

2

This thing can be optimized very quickly. For starters you are creating a new connection to the database with every function call. I don't know for sure if the connection is closed when the PDO object goes out of scope but nevertheless it's bad design.


UPDATE

PHP will close the connection to the database when the PDO object is destroyed. Reference http://php.net/manual/en/pdo.connections.php

于 2013-03-13T18:28:21.033 回答
1

$db->rollBack() make a roll back for the transaction. If you don't know what transactions are there is no point for you to use them, because it creates an unnecessary overhead for the server.

commit() permanently writes the data from the query, rollback() undo everything to the state where you called beginTransaction()

Transactions are to be used when its crucial that changes in more then one place happens simultaneously, imagine a transaction of money between two accounts. On simple selects there is absolutely no need for transactions.

(I'm also sceptic to how you use try/catch)

However... If you run one query directly on the db server, is it also slow? Do you open/close the db connection between each call? (if so -(yes)- don't). What is the network relationship between the http/db server?

于 2013-03-13T18:29:03.030 回答
1

尝试使用分析器来确定您的瓶颈在哪里 - xdebug 中包含一个。鉴于此代码的简单性,它可​​能是查询本身 - 尝试使用 mysql cli 客户端或 MySQL Workbench 独立运行查询,然后查看您返回的时间。如果是查询很慢,你可以使用 EXPLAIN 和 MySQL 手册中丰富的优化部分来改进它。

于 2013-03-13T18:16:49.160 回答
0

我忍不住重写你的函数,删除无用的部分并添加必要的部分

function util_db_access($type, $statement, $array) {
    static $db;

    if (empty($db)) {
        $dsn = 'mysql:host=localhost;dbname=db;charset=UTF8';
        $opt = array(
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
        );
        $db = new PDO($dsn, 'user', 'pass', $opt);
    }

    $stmt = $db->prepare($statement);
    $stmt->execute($array);
    if($type == 'all') {
        return $stmt->fetchAll();
    }
    if($type == 'row') {
        return $stmt->fetch();
    }
    if($type == 'one') {
        return $stmt->fetchColumn();
    }
    if($type == 'id') {
        return $db->lastInsertId();
    }
    if($type == 'numrows') {
        return $stmt->rowCount();
    }
}

这个新版本很可能也不会受到任何延迟

现在您可以毫无延迟或不便地使用这个强大的功能:

$user = util_db_access("row", "SELECT * FROM users WHERE id = ?", array($someId));
$id   = util_db_access("id", "INSERT INTO users SET name=?", array($name));

等等

但是,为此目的仅具有一个功能是很不方便的,我希望您能尽快将它纳入课堂。您可以将我的Safemysql课程作为一些想法的来源。

于 2013-03-13T18:31:59.993 回答