简体   繁体   中英

MySQL Poor performance INSERT or PHP PDO

Usually when a user comes to my website he 'subscribes' to around an average of ~50 events at once, which we save in a mapping_table that links many users to many events. maping_table has around 50k entries, growing by several hundreds each day.

INSERT ing those ~50 lines in the mapping table takes around 10 to 20 seconds which makes my website appear very slow.

I reach a point where I can't figure out how to improve the following PHP or SQL in order to lower the INSERT time as it seems pretty basic.

Here is the SHOW CREATE statement :

    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

My php script for the insert part :

    $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();
    }

I'm open to any suggestions.

Additional information :

If I microtime each insert I get an average of 300ms to 1sec per insert.

I have tried deleting the UNIQUE KEY , then all FOREIGN KEYS , then all INDEXES but those did not make any difference in performace.

Following comments on my questions I modified my php as follow for 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();

This decreased my average insert to less than 10ms per line inserted (as opposed to 300ms to 1sec per line previously). Never thought the difference would be that big. Thanks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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