MySQL 性能不佳 INSERT 或 PHP PDO
Posted
技术标签:
【中文标题】MySQL 性能不佳 INSERT 或 PHP PDO【英文标题】:MySQL Poor performance INSERT or PHP PDO 【发布时间】:2016-03-10 12:42:39 【问题描述】:通常,当用户访问我的网站时,他平均一次“订阅”大约 50 个事件,我们将其保存在 mapping_table
中,它将许多用户链接到许多事件。 maping_table
有大约 50k 个条目,每天增长数百个。
INSERT
映射表中这大约 50 行大约需要 10 到 20 秒,这使我的网站看起来很慢。
我无法弄清楚如何改进以下 php 或 SQL 以降低 INSERT 时间,因为它看起来很基本。
这是SHOW CREATE
声明:
CREATE TABLE `mapping_table` (
`user_id` char(21) NOT NULL,
`event_id` char(21) NOT NULL,
`update_id` char(10) NOT NULL,
PRIMARY KEY (`user_id`,`event_id`),
KEY `event` (`event_id`),
CONSTRAINT `mapping_table_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users_table` (`user_id`) ON DELETE CASCADE ON UPDATE NO ACTION,
CONSTRAINT `mapping_table_ibfk_2` FOREIGN KEY (`event_id`) REFERENCES `events_table` (`event_id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1
我的插入部分的 php 脚本:
$update_id = 'RandomString';
$conn = new PDO($pdo_serv, $db_user, $db_pwd);
$stmt = $conn->prepare("INSERT INTO `mapping_table` (`user_id`, `event_id`, `update_id`)
VALUES (:uid,:eid,:upd)");
//GO THROUGH EACH USER SUBSCRIBED EVENTS AND INSERT THEM
foreach($subscribed_events AS $event)
$stmt->bindParam(':uid', $userid);
$stmt->bindParam(':eid', $event->id);
$stmt->bindParam(':upd', $update_id);
$stmt->execute();
我愿意接受任何建议。
其他信息:
如果我 microtime
每次插入,我平均每次插入需要 300 毫秒到 1 秒。
我尝试删除UNIQUE KEY
,然后是所有FOREIGN KEYS
,然后是所有INDEXES
,但这些对性能没有任何影响。
【问题讨论】:
尝试批量插入,而不是单个插入查询。 尝试将AUTO_INCREMENT
数字主键添加到关系表中,并尝试在单个事务中处理所有INSERT
s。
我现在会尝试批次INSERT
,我会告诉你的。我认为 PDO prepare()
和 execute()
在多个连续查询中非常有效,因此我选择了设计。
这里有几个例子***.com/questions/1176352/…
其他问题...不要使用CHAR
,除非该列确实是固定长度的。而是使用VARHAR
。
【参考方案1】:
根据我的问题,我修改了我的 php,如下batch INSERT
:
$update_id = 'RandomString';
$conn = new PDO($pdo_serv, $db_user, $db_pwd);
$sql = "INSERT INTO `mapping_table` (`user_id`, `event_id`, `update_id`)
VALUES ";
$values = "";
//GO THROUGH EACH USER SUBSCRIBED EVENTS GENERATE VALUES STRING
foreach($subscribed_events AS $event)
$values .= "('".$userid."','".$event->id."','".$update_id."'),"
//Proceed batch insert
$values = rtrim($values, ",");
$sql .= $values;
$stmt = $conn->prepare($sql);
$stmt->execute();
这将我的平均插入时间减少到每行插入不到 10 毫秒(与之前的每行 300 毫秒到 1 秒相比)。没想到差距会这么大。谢谢。
【讨论】:
如果您出于性能原因观看了此问题,但想保持一点安全,请务必致电$conn->quote($userid)
而不是 $userid
。它会稍微减慢整个过程。即使你绝对确定你的数据源,你也不能保证这在 1 个月,1 年,......所以一定要使用它,最终不会花费太多。以上是关于MySQL 性能不佳 INSERT 或 PHP PDO的主要内容,如果未能解决你的问题,请参考以下文章