php - 一个简单的 MySQL 插入/更新怎么会比外部 Web 请求慢呢?

标签 php mysql

由于一些性能问题,我一直在优化多个 SQL 查询并向某些表/列添加索引以加快速度。

在 PHP 中使用 microtime() 运行一些时间测试(循环查询数百次并在每个循环中调用 RESET QUERY CACHE)。我对执行 3 件事的函数之一的结果感到有些困惑:

  1. sessions 表 (InnoDB) 中插入一行。
  2. 更新users 表 (InnoDB) 中的一行。
  3. 将 session ID 发送到远程服务器,远程服务器将 session ID 插入到它自己的 session 表 (MongoDB) 中。

步骤 1. 通常需要 30 - 40 毫秒,步骤 2. 20 - 30 毫秒,步骤 3. 7 - 20 毫秒。

我尝试查找 MySQL 的一些预期查询时间,但没有找到任何有用的东西,所以我不知道会发生什么。话虽如此,这些查询时间似乎有点长,我肯定不会期望 Web 请求比对本地数据库的 MySQL 查询更快地完成。

知道这些查询时间与网络请求相比是否合理吗?

SQL/系统信息

两台服务器(远程服务器和带有 MySQL 数据库的服务器)都是在同一物理服务器上运行的虚拟服务器,具有共享存储(多个 SSD raid 目标)。远程服务器分配有单个 CPU 和 2 GB RAM,MySQL 服务器分配有 8 个 CPU 和 32 GB RAM。两台服务器位于同一 LAN 上。

session 插入查询:

 INSERT INTO sessions (
  session_id,
  user_id,
  application,
  machine_id,
  user_agent,
  ip,
  method,
  created,
  last_active,
  expires
)
VALUES (
  string, // session_id
  int, // user_id
  string, // application
  string, // machine_id
  string, // user_agent
  string, // ip
  string, // method
  CURRENT_TIMESTAMP, // created
  CURRENT_TIMESTAMP, // last_active
  NULL / FROM_UNIXTIME([PHP timestamp]) // expires
)

sessions 表(包含约 500'000 行);

+-------------+---------------+------+-----+---------+----------------+
| Field       | Type          | Null | Key | Default | Extra          |
+-------------+---------------+------+-----+---------+----------------+
| sessions_id | int(11)       | NO   | PRI | NULL    | auto_increment |
| session_id  | char(32)      | NO   | UNI | NULL    |                |
| user_id     | int(11)       | NO   | MUL | NULL    |                |
| application | varchar(128)  | NO   |     | NULL    |                |
| machine_id  | varchar(36)   | NO   |     | NULL    |                |
| user_agent  | varchar(1024) | NO   |     | NULL    |                |
| ip          | varchar(15)   | NO   |     | NULL    |                |
| method      | varchar(20)   | NO   |     | NULL    |                |
| created     | datetime      | NO   |     | NULL    |                |
| last_active | datetime      | NO   |     | NULL    |                |
| expires     | datetime      | YES  | MUL | NULL    |                |
+-------------+---------------+------+-----+---------+----------------+

用户更新查询:

UPDATE users
SET last_active = string // For example '2016-01-01 00:00:00'
WHERE user_id = int

users 表(包含约 200,000 行):

+------------------------+---------------------+------+-----+---------+----------------+
| Field                  | Type                | Null | Key | Default | Extra          |
+------------------------+---------------------+------+-----+---------+----------------+
| user_id                | int(11)             | NO   | PRI | NULL    | auto_increment |
| username               | varchar(64)         | NO   | MUL | NULL    |                |
| first_name             | varchar(256)        | NO   |     | NULL    |                |
| last_name              | varchar(256)        | NO   |     | NULL    |                |
| info                   | varchar(512)        | NO   |     | NULL    |                |
| address1               | varchar(512)        | NO   |     | NULL    |                |
| address2               | varchar(512)        | NO   |     | NULL    |                |
| city                   | varchar(256)        | NO   |     | NULL    |                |
| zip_code               | varchar(128)        | NO   |     | NULL    |                |
| state                  | varchar(256)        | NO   |     | NULL    |                |
| country                | varchar(128)        | NO   |     | NULL    |                |
| locale                 | varchar(5)          | NO   |     | NULL    |                |
| phone                  | varchar(128)        | NO   |     | NULL    |                |
| email                  | varchar(256)        | NO   | MUL | NULL    |                |
| password               | char(60)            | NO   | MUL | NULL    |                |
| permissions            | bigint(20) unsigned | NO   |     | 0       |                |
| created                | datetime            | YES  |     | NULL    |                |
| last_active            | datetime            | YES  |     | NULL    |                |
+------------------------+---------------------+------+-----+---------+----------------+

最佳答案

看来问题只是我们的 MySQL 设置(它们都是默认的)。

我在users更新查询上运行了MySQL配置文件,发现query end步骤占用了执行查询的大部分时间。

谷歌搜索让我找到了https://stackoverflow.com/a/12446986/736247 - 而不是直接使用所有建议的值(这是不推荐的,因为其中一些可能会对数据完整性产生不利影响)我找到了一些更多信息,包括 Percona 上的此页面:https://www.percona.com/blog/2013/09/20/innodb-performance-optimization-basics-updated/ .

InnoDB 启动选项和系统变量也很有用:http://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html也很有用。

我最终为以下设置设置了新值:

  • innodb_flush_log_at_trx_commit
  • innodb_flush_method
  • innodb_buffer_pool_size
  • innodb_buffer_pool_instances
  • innodb_log_file_size

这导致查询时间显着缩短(以与我在问题中相同的方式测量):

  1. sessions 表中插入一行:约 8 毫秒(从 30-40 毫秒缩短)。
  2. 更新 users 表中的一行:约 2.5 毫秒(从 20-30 毫秒缩短)。

关于php - 一个简单的 MySQL 插入/更新怎么会比外部 Web 请求慢呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35728274/

相关文章:

php - 无法使用 SF2 将上传的文件保存到文件系统

mysql - 在mysql中查找所有没有空约束的表

php - 带有动态属性名称的 isset()

php - fwrite不写

php - 如何在 phpword 中更改字体(名称、大小、行间距)?

php - 相乘并输出和 mysql php

php - 使用 Inner Join MySQL php 从 3 个表中获取数据

php - 使用同一查询更新两行

php - 使用 PHP 和 MySQL 上传文件

mysql - 如何删除以撇号开头的表格