This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
Is the database query faster if I insert multiple rows at once:
like
INSERT....
UNION
INSERT....
UNION
(I need to insert like 2-3000 rows)
INSERT statements that use VALUES syntax can insert multiple rows. To do this, include multiple lists of column values, each enclosed within parentheses and separated by commas.
Example:
INSERT INTO tbl_name
(a,b,c)
VALUES
(1,2,3),
(4,5,6),
(7,8,9);
Source
If you have your data in a text-file, you can use LOAD DATA INFILE.
When loading a table from a text file, use LOAD DATA INFILE. This is usually 20 times faster than using INSERT statements.
Optimizing INSERT Statements
You can find more tips on how to speed up your insert statements on the link above.
Just use a SELECT statement to get the values for many lines of the chosen columns and put these values into columns of another table in one go. As an example, columns "size" and "price" of the two tables "test_b" and "test_c" get filled with the columns "size" and "price" of table "test_a".
BEGIN;
INSERT INTO test_b (size, price)
SELECT size, price
FROM test_a;
INSERT INTO test_c (size, price)
SELECT size, price
FROM test_a;
COMMIT;
The code is embedded in BEGIN and COMMIT to run it only when both statements have worked, else the whole run up to that point gets withdrawn.
Here is a PHP solution ready for use with a n:m (many-to-many relationship) table :
// get data
$table_1 = get_table_1_rows();
$table_2_fk_id = 123;
// prepare first part of the query (before values)
$query = "INSERT INTO `table` (
`table_1_fk_id`,
`table_2_fk_id`,
`insert_date`
) VALUES ";
//loop the table 1 to get all foreign keys and put it in array
foreach($table_1 as $row) {
$query_values[] = "(".$row["table_1_pk_id"].", $table_2_fk_id, NOW())";
}
// Implode the query values array with a coma and execute the query.
$db->query($query . implode(',',$query_values));
EDIT : After #john's comment I decided to enhance this answer with a more efficient solution :
divides the query to multiple smaller queries
use rtrim() to delete last coma instead of implod()
// limit of query size (lines inserted per query)
$query_values = "";
$limit = 100;
$table_1 = get_table_1_rows();
$table_2_fk_id = 123;
$query = "INSERT INTO `table` (
`table_1_fk_id`,
`table_2_fk_id`,
`insert_date`
) VALUES ";
foreach($table_1 as $row) {
$query_values .= "(".$row["table_1_pk_id"].", $table_2_fk_id, NOW()),";
// entire table parsed or lines limit reached :
// -> execute and purge query_values
if($i === array_key_last($table_1)
|| fmod(++$i / $limit) == 0) {
$db->query($query . rtrim($query_values, ','));
$query_values = "";
}
}
// db table name / blog_post / menu / site_title
// Insert into Table (column names separated with comma)
$sql = "INSERT INTO product_cate (site_title, sub_title)
VALUES ('$site_title', '$sub_title')";
// db table name / blog_post / menu / site_title
// Insert into Table (column names separated with comma)
$sql = "INSERT INTO menu (menu_title, sub_menu)
VALUES ('$menu_title', '$sub_menu', )";
// db table name / blog_post / menu / site_title
// Insert into Table (column names separated with comma)
$sql = "INSERT INTO blog_post (post_title, post_des, post_img)
VALUES ('$post_title ', '$post_des', '$post_img')";
Related
This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
Is the database query faster if I insert multiple rows at once:
like
INSERT....
UNION
INSERT....
UNION
(I need to insert like 2-3000 rows)
INSERT statements that use VALUES syntax can insert multiple rows. To do this, include multiple lists of column values, each enclosed within parentheses and separated by commas.
Example:
INSERT INTO tbl_name
(a,b,c)
VALUES
(1,2,3),
(4,5,6),
(7,8,9);
Source
If you have your data in a text-file, you can use LOAD DATA INFILE.
When loading a table from a text file, use LOAD DATA INFILE. This is usually 20 times faster than using INSERT statements.
Optimizing INSERT Statements
You can find more tips on how to speed up your insert statements on the link above.
Just use a SELECT statement to get the values for many lines of the chosen columns and put these values into columns of another table in one go. As an example, columns "size" and "price" of the two tables "test_b" and "test_c" get filled with the columns "size" and "price" of table "test_a".
BEGIN;
INSERT INTO test_b (size, price)
SELECT size, price
FROM test_a;
INSERT INTO test_c (size, price)
SELECT size, price
FROM test_a;
COMMIT;
The code is embedded in BEGIN and COMMIT to run it only when both statements have worked, else the whole run up to that point gets withdrawn.
Here is a PHP solution ready for use with a n:m (many-to-many relationship) table :
// get data
$table_1 = get_table_1_rows();
$table_2_fk_id = 123;
// prepare first part of the query (before values)
$query = "INSERT INTO `table` (
`table_1_fk_id`,
`table_2_fk_id`,
`insert_date`
) VALUES ";
//loop the table 1 to get all foreign keys and put it in array
foreach($table_1 as $row) {
$query_values[] = "(".$row["table_1_pk_id"].", $table_2_fk_id, NOW())";
}
// Implode the query values array with a coma and execute the query.
$db->query($query . implode(',',$query_values));
EDIT : After #john's comment I decided to enhance this answer with a more efficient solution :
divides the query to multiple smaller queries
use rtrim() to delete last coma instead of implod()
// limit of query size (lines inserted per query)
$query_values = "";
$limit = 100;
$table_1 = get_table_1_rows();
$table_2_fk_id = 123;
$query = "INSERT INTO `table` (
`table_1_fk_id`,
`table_2_fk_id`,
`insert_date`
) VALUES ";
foreach($table_1 as $row) {
$query_values .= "(".$row["table_1_pk_id"].", $table_2_fk_id, NOW()),";
// entire table parsed or lines limit reached :
// -> execute and purge query_values
if($i === array_key_last($table_1)
|| fmod(++$i / $limit) == 0) {
$db->query($query . rtrim($query_values, ','));
$query_values = "";
}
}
// db table name / blog_post / menu / site_title
// Insert into Table (column names separated with comma)
$sql = "INSERT INTO product_cate (site_title, sub_title)
VALUES ('$site_title', '$sub_title')";
// db table name / blog_post / menu / site_title
// Insert into Table (column names separated with comma)
$sql = "INSERT INTO menu (menu_title, sub_menu)
VALUES ('$menu_title', '$sub_menu', )";
// db table name / blog_post / menu / site_title
// Insert into Table (column names separated with comma)
$sql = "INSERT INTO blog_post (post_title, post_des, post_img)
VALUES ('$post_title ', '$post_des', '$post_img')";
I'm trying to run a pretty simple script that does the following: Takes the id of a content module and assigns it to multiple locations
So say I click the link on a content module with ID of 123, I want to assign it to all multiple locations. In SQL I would just say :
INSERT INTO table (cont_id,loc_id)
VALUES (123, select(id from location_table where active = 1))
I'm currently using this:
$pageID = $_GET['pageID'];
$assignPage = "
INSERT INTO locationContent(page_id, display_id)
VALUES ( '$pageID', select(id from locations where active = 1))
ON DUPLICATE KEY UPDATE active = 1
";
$performAssign = $mysqlConn->query($assignPage);
The issue I'm wondering about though, is do I need to put this into a foreach or while loop? If I were to just run as is, I feel like that would only work for one record
You seem to be looking for MySQL INSERT ... SELECT syntax.
From the documentation:
With INSERT ... SELECT, you can quickly insert many rows into a table from the result of a SELECT statement, which can select from one or many tables.
Query:
INSERT INTO locationContent (page_id, display_id)
SELECT ?, id FROM locations WHERE active = 1
ON DUPLICATE KEY UPDATE active = 1
The ? stands for parameter $pageID (you do want to use parameterized queries and prepared statement to protect your code against SQL injection).
You can't mix the INSERT INTO .. VALUES and INSERT INTO ... SELECT syntax, however SELECT constant, var FROM .. is possible like:
$assignPage = $mysqlConn->prepare("
INSERT INTO locationContent(page_id, display_id)
SELECT :page as page_id, id FROM locations WHERE active = 1
ON DUPLICATE KEY UPDATE active = 1
";
$performAssign = $assignPage->execute(array('page' =>$pageID));
I want to insert multiple row in sql with php, after checking few conditions.
The condition is, if 'cat' and 'preview' is not null then row one will be submitted and if 'cat','preview','cat2','preview2' is not null then two row will submitted with first row's value 'cat' and'preview and 2nd row's value 'cat2' and 'preview2'.
i tried these code, but i see - Undefined variable: sql
whats wrong with my condition?
else if(isset($cat)and ($cat!=="") and isset($preview)and ($preview=="") and
(isset($cat2))and ($cat2!=="") and (isset($preview2))and ($preview2!==""))
{
$sql = "INSERT INTO files (cat, preview, file, art) VALUES
('".$cat."','".$preview."','".$file."','".$art."')
('".$cat2."','".$preview2."','".$file2."','".$art2."')";
}
your code just had query mistake that you wanted to insert two row in just one insert command.use this code that seperates the insert commands :
else if(!empty($cat) and !empty($preview) and
!empty($cat2) and !empty($preview2))
{
$sql = "INSERT INTO files (cat, preview, file, art) VALUES
('".$cat."','".$preview."','".$file."','".$art."');";
$sql .= " INSERT INTO files (cat, preview, file, art) VALUES ('".$cat2."','".$preview2."','".$file2."','".$art2."');";
}
I personally think that the logic you have with your conditions may need rethinking. For instance, if you save your values into arrays, you can automate this process:
// Save first values
$sqlArgs[] = array($cat,$preview,$file,$art);
// Save second values
$sqlArgs[] = array($cat2,$preview2,$file2,$art2);
// Loop through each row.
foreach($sqlArgs as $key => $array) {
// If the `cat` or the `preview` empty, skip
if(!empty(trim($array[0])) && !empty(trim($array[1])))
$sql[] = "'".implode("','",$array)."'";
}
// If the sql has rows continue
if(!empty($sql)) {
// Build the statement rows with implode() of values.
// This assumes these are not user-input values or that you have
// thoroughly sanitized the values.
$statement = "INSERT INTO `files` (`cat`,`preview`,`file`,`art`) VALUES (".implode("),(",$sql).")";
// Preview statement
print_r($statement);
}
This approach will take care of 0,1, or 2 inserts (or more if necessary) based on the two keys cat & preview being filled.
Insert query with ; is not one query...
For example
Insert into mytable (a,b,c) values (1,2,3);
Insert into mytable (a,b,c) values (4,5,6);
Insert into mytable (a,b,c) values (7,8,9);
is not one query, this is 3 insert queries.
That is mean when insert values (4,5,6) have error, values (1,2,3) query is successed....
We want if one row failed, all insert query fail.
Therefore, we don't write insert query with ;
Example query:
Insert into mytable values(1, 2, 3), (4, 5, 6), (7, 8, 9);
This question already has answers here:
Insert multiple rows with one query MySQL
(5 answers)
Closed 2 years ago.
Is this legal?
$string1= "INSERT INTO....;";
$string1 .= "INSERT INTO....;";
$string1 .= "INSERT INTO....;";
mysql_query($string1) or die(mysql_error());
For what it's worth, and depending on if you're inserting the same data into
the same tables, it's much better to insert multiple values with the one insert
e.g.
INSERT INTO a VALUES (1,23),(2,34),(4,33);
INSERT INTO a VALUES (8,26),(6,29);
No, mysql_query() only allows one query at a time.
You can insert multiple rows like this:
INSERT INTO table (col1, col2)
VALUES (1, 2), (3, 4), (5, 6)
From MySQL dev support MySQL dev forum
INSERT INTO table (artist, album, track, length)
VALUES
("$artist", "$album", "$track1", "$length1"),
("$artist", "$album", "$track2", "$length2"),
("$artist", "$album", "$track3", "$length3"),
("$artist", "$album", "$track4", "$length4"),
("$artist", "$album", "$track5", "$length5");
So insert goes as normal as always:
naming first the table name where we want to insert new row,
followed by naming column names in round brackets (Note: Not needed if you want to insert ALL columns),
followed by VALUES key name and then in round brackets comes the values that you want to insert for new ROW in the above table,
followed by COMMA and then another pair of round brackets with new values for new row in the mentioned table above
and this repeats N-times as long you have the data to insert.
Happy inserting multiple values with ONE insert statement. :)
Copy/paste example within a function and a loop (suppose $ids is an array)
public function duplicateItem($ids)
{
if (isset($ids[0])){ //at least one item
$sqlQuery = "INSERT INTO items (item_id, content) VALUES ";
for($i=0; $i<count($ids); $i++) {
if ($i == count($ids)-1){
$sqlQuery .= "(".$ids[$i][0].", '".$ids[$i][1]."');";
}else{
$sqlQuery .= "(".$ids[$i][0].", '".$ids[$i][1]."'),";
}
}
mysql_query($sqlQuery) or die('Error, insert query failed: '.mysql_error());
}
}
In general, that's valid SQL since each statement ends with a semicolon, but PHP doesn't allow you to send more than one query at a time, in order to protect against SQL injection attacks that might exploit a poorly written script.
You can still use a syntax like:
INSERT INTO foo VALUES ('a1', 'b1'), ('a2', 'b2');
INSERT INTO table (a,b) VALUES (1,2), (2,3), (3,4);
No. They are separate queries, and must be called as such.
// if $data is an array
$sqlQuery ="INSERT INTO tableName(col1, col2) VALUES ";
for($i=0; $i<count($data); $i++) {
$sqlQuery .="(".$data[$i][0].", '".$data[$i][1]."'),";
}
$sqlQuery = rtrim($sqlQuery, ','); // Remove last comma
mysql_query($sqlQuery) or die('Error, insert query failed: '.mysql_error());
I have a scripts that retrieves huge data on a table. I want to create a mysqldump to insert data into another database table with different fields. I want the format of phpMyAdmin where it repeats the INSERT INTO Table VALUES(values1),(values2), ...(values100); if reaches certain amount of value sets depends on what you set.
ex: If I have 550 data sets and i want to be devided the data by 100 so that i will have 6 sets of INSERT INTO query.
INSERT INTO tablename VALUES(value1), (value2), .... (value100);
INSERT INTO tablename VALUES(value101), (value102), .... (value200);
INSERT INTO tablename VALUES(value201), (value202), .... (value300);
INSERT INTO tablename VALUES(value301), (value302), .... (value400);
INSERT INTO tablename VALUES(value401), (value402), .... (value500);
INSERT INTO tablename VALUES(value501), (value502), .... (value550);
If you're using mysqldump and wish to output mutiple rows into a single insert, then you need to use the --extended-insert option:
mysqldump extended insert option
I'm not sure it's possible to specify with mysqldump to specify that a specific number of rows are included in each INSERT statement generated in the dump. Rather you can set the net_buffer_length (although it's not recommended that you do change it), so the actual amount may vary depending on the data in each row.
You could use array_chunk(), something like:
$toInsert = array( '(values1)', '(values2)', '(values3)', '(values4)' ); //etc.
$sqlStart = 'INSERT INTO tablename (field1, field2, field3, etc) VALUES ';
foreach (array_chunk($toInsert, 100) as $insertSet) {
$sql = $sqlStart . implode(', ', $insertSet);
//execute $sql
}
Are you actually doing much with the data though? You might be able to do it all in SQL with INSERT INTO table (field1, field2) SELECT somefield, somefield2 FROM another table
While fetching the rows, increment a counter, and when it hits a certain value, have it create a new insert statement?
Some code that might not be correct (no PHP for a LONG time), but you will probably get the idea
$i = 0;
$insertstatements = array();
$currentinsertstatement;
while ($temp = mysql_fetch_assoc($result)) {
// do something with the data
$insertpart = "(value_xxx)";
if ($i % 100 == 0) {
// first value
if ($i != 0) $insertstatements[count($insertstatements)] = $currentinsertstatement;
$currentinsertstatement = "INSERT INTO tablename VALUES " . $insertpart;
} else {
$currentinsertstatement .= ", " . $insertpart;
// somewhere in the middle of the insert statement
}
$i++;
}
if ($i % 100 != 0) {
$insertstatements[count($insertstatements] = $currentinsertstatement;
}
You definitely should use transactions for huge inserts, if your storage engine supports them (like innoDB):
BEGIN;
INSERT INTO tablename VALUES...
INSERT INTO tablename VALUES...
COMMIT;
If something goes wrong, you can safely ROLLBACK the last operation, restart you script, etc.