通常当用户访问我的网站时,他会同时“订阅”大约50个事件,我们将其保存在mapping_table
中,将许多用户链接到许多事件。 maping_table
有大约5万个条目,每天增加数百个。
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
,但这些效果没有任何差别。
答案 0 :(得分:0)
在对我的问题发表评论之后,我将我的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秒)。从来没有想过差异会那么大。感谢。