繁体   English   中英

MySql 性能慢

[英]Slow performance MySql

我正在尝试我正在构建的系统的性能,它真的很慢,我不知道为什么或是否应该这么慢。 我正在测试的是我可以对数据库执行多少次 INSERT,每秒大约 22 次。 这听起来真的很慢,当我尝试插入 ia singel big SQL-query 时,我可以在大约 0.5 秒内插入 30000 条记录。 在现实生活中,插入是由系统中的不同用户进行的,因此连接、发送查询、解析查询等的开销将始终存在。 到目前为止我尝试过的:

  • mysqli 用尽可能少的代码。 = 22 每秒插入
  • 使用尽可能少的代码的 PDO。 = 22 每秒插入
  • 将连接主机从 localhost 更改为 127.0.0.1 = 22 INSERT 每秒
  • 没有语句对象的 mysqli 并检查 SQL 注入 = 每秒 22 次插入

所以这里有些地方是错误的。

系统规格:

  • 英特尔 i5
  • 16 公制内存
  • 7200 转磁盘驱动器

软件:

  • 视窗 10
  • XAMPP,MariaDB 相当新
  • 数据库引擎 innoDB。

我用来做测试的代码:

$amountToInsert = 1000;
//$fakeData is an array with randomly generated emails 
$fakeData = getFakeData($amountToInsert); 
$db = new DatabaseHandler();
for ($i = 0; $i < $amountToInsert; $i++) {
    $db->insertUser($fakeUsers[$i]);
}
$db->closeConnection();

调用数据库的类:

class DatabaseHandler {
    private $DBHOST = 'localhost';
    private $DBUSERNAME = 'username';
    private $DBPASSWORD = 'password';
    private $DBNAME = 'dbname';
    private $DBPORT = 3306;

    private $mDb;

    private $isConnected = false;

    public function __construct() {
        $this->mDb = new mysqli($this->DBHOST, $this->DBUSERNAME
                              , $this->DBPASSWORD, $this->DBNAME
                              , $this->DBPORT);
        $this->isConnected = true;
    }

    public function closeConnection() {
        if ($this->isConnected) {
            $threadId = $this->mDb->thread_id;
            $this->mDb->kill($threadId);
            $this->mDb->close();
            $this->isConnected = false;
        }
    }

    public function insertUser($user) {
        $this->mDb->autocommit(true);
        $queryString = 'INSERT INTO `users`(`email`, `company_id`) '
                        .'VALUES (?, 1)';
        $stmt = $this->mDb->prepare($queryString);
        $stmt->bind_param('s', $user);
        if ($stmt->execute()) {
            $stmt->close();
            return 1;
        } else {
            $stmt->close();
            return 0;
        }
    }
}

“用户”表有 4 列,结构如下:

  • id INT 无符号主键
  • 电子邮件 VARCHAR(60)
  • company_id INT 无符号索引
  • 指导文本

我在这里不知所措,真的不知道下一步该往哪里看。 任何在正确方向上的帮助将不胜感激。

就像评论中解释的那样,应该归咎于 InnoDB。 默认情况下,此引擎过于谨慎,不使用磁盘缓存,以确保数据确实已写入磁盘,然后再向您返回成功消息。 所以你基本上有两个选择。

  1. 大多数时候你只是不关心确认的写入。 因此,您可以通过将此 mysql 选项设置为零来配置 mysql:

     innodb_flush_log_at_trx_commit = 0

    只要以这种方式设置,您的 InnoDB 写入将几乎与 MyISAM 一样快。

  2. 另一种选择是将您的所有写入包装在一个事务中。 因为它只需要来自所有写入的单一确认,所以它也将是合理的快速。

当然,通过多次插入只准备一次查询是明智的,但与上述问题相比,速度增益可以忽略不计。 因此,它既不能作为解释,也不能作为对此类问题的补救措施。

您的测试不是判断性能的好方法。 为什么,因为你准备了 1000 次陈述。 这不是准备好的语句应该使用的方式。 语句准备一次,不同的参数绑定多次。 尝试这个:

public function __construct() {
    $this->mDb = new mysqli($this->DBHOST, $this->DBUSERNAME
                          , $this->DBPASSWORD, $this->DBNAME
                          , $this->DBPORT);
    $this->isConnected = true;
    $queryString = 'INSERT INTO `users`(`email`, `company_id`) '
                    .'VALUES (?, 1)';
    $this->stmt_insert = $this->mDb->prepare($queryString);

}

public function insertUser($user) {
    $this->stmt_insert->bind_param('s', $user);
    if ($this->stmt_insert->execute()) {
        return 1;
    } else {
        return 0;
    }
}

而且,您将看到性能的巨大提升。 所以总结一下,你的系统没有任何问题,只是测试不好。

更新:

你的常识有一点关于提前准备和重用准备好的语句不会产生很大的推动作用。 我测试发现它大约是 5-10%

然而,有一些东西确实给了很大的推动。 关闭自动提交!。 插入 100 条记录,以前平均需要大约 4.7 秒,现在平均不到 0.5 秒!

$con->自动提交(假);

/循环/ $con->commit();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM