Sha*_*ank 11 mysql innodb memory prepared-statement php
我正在开发一个涉及大量数据库写入的应用程序,大约 70% 的插入和 30% 的读取。这个比率还包括我认为是一次读取和一次写入的更新。通过插入语句,多个客户端通过下面的插入语句在数据库中插入数据:
$mysqli->prepare("INSERT INTO `track` (user, uniq_name, ad_name, ad_delay_time ) values (?, ?, ?, ?)");
Run Code Online (Sandbox Code Playgroud)
问题是我应该使用insert_delay还是使用mysqli_multi_query机制,因为 insert 语句在服务器上使用 ~100% cpu。我在我的数据库上使用 InnoDB 引擎,所以插入延迟是不可能的。服务器上的插入是 ~36k/hr 和 99.89% 读取,我也在使用 select 语句在单个查询中检索数据七次,这个查询在服务器上执行需要 150 秒。我可以使用什么样的技术或机制来完成这项任务?我的服务器内存是 2 GB,我应该扩展内存吗?。看看这个问题,任何建议将不胜感激。
表的结构:
+-----------------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user | varchar(100) | NO | | NULL | |
| uniq_name | varchar(200) | NO | | NULL | |
| ad_name | varchar(200) | NO | | NULL | |
| ad_delay_time | int(11) | NO | | NULL | |
| track_time | timestamp | NO | MUL | CURRENT_TIMESTAMP | |
+-----------------+--------------+------+-----+-------------------+----------------+
Run Code Online (Sandbox Code Playgroud)
我的数据库当前状态,它显示 41k 插入(写入),这对我的数据库来说非常慢。
Rol*_*DBA 12
由于您有更多的写入然后读取,我想推荐以下内容
由于InnoDB 不支持 INSERT DELAYED,因此使用大型 InnoDB 缓冲池是最接近 INSERT DELAYED 的方法。所有 DML(插入、更新和删除)都将缓存在 InnoDB 缓冲池中。写入的事务信息会立即写入重做日志(ib_logfile0、ib_logfile1)。在缓冲池中发布的写入通过 ibdata1(用于二级索引的插入缓冲区,双写入缓冲区)定期从内存刷新到磁盘。缓冲池越大,可以缓存的 INSERT 数量就越大。在具有 8GB 或更多 RAM 的系统中,使用 75-80% 的 RAM 作为 innodb_buffer_pool_size。在 RAM 非常少的系统中,为 25%(以适应操作系统)。
CAVEAT :您可以将innodb_doublewrite设置为 0 以进一步加快写入速度,但要冒数据完整性的风险。您还可以通过将innodb_flush_method设置为 O_DIRECT 以防止将 InnoDB 缓存到操作系统来加快速度。
默认情况下,重做日志命名为 ib_logfile0 和 ib_logfile1,每个大小为 5MB。大小应该是 innodb_buffer_pool_size 的 25%。如果重做日志已经存在,在 my.cnf 中添加新设置,关闭 mysql,删除它们,然后重新启动 mysql。
日志缓冲区在将更改刷新到重做日志之前保存 RAM 中的更改。默认为 8M。日志缓冲区越大,磁盘 I/O 就越少。处理非常大的事务时要小心,因为这可能会使 COMMIT 慢几毫秒。
MySQL 5.5 和 MySQL 5.1 InnoDB 插件具有让 InnoDB 存储引擎访问多个 CPU 的设置。以下是您需要设置的选项:
如果您有 MySQL 5.0,请升级到 MySQL 5.5。如果您有 MySQL 5.1.37 或更低版本,请升级到 MySQL 5.5。如果您有 MySQL 5.1.38 或更高版本并希望继续使用 MySQL 5.1,请安装 InnoDB 插件。这样,您就可以利用 InnoDB 的所有 CPU。
INT(2) 仍然使用 4 个字节——也许您的意思是 TINYINT UNSIGNED?
setno 有多少个不同的值?如果它很小,则 KEY(setno) 将永远不会被使用。INSERTing 必须更新该索引;删除 KEY 会加速 INSERT 一些。
CHAR(10) --flag
长度总是 10 个字符吗?那么用utf8呢?也许你可以使用标志 VARCHAR(10) CHARACTER SET ascii
批量插入——一次插入 100 个,运行速度提高 10 倍。(超过 100 就进入“收益递减”状态。)
自动提交的价值是什么?您是否将每个 INSERT 包装在 BEGIN...COMMIT 中?innodb_flush_log_at_trx_commit 的值是多少?