Codeigniter batch insert performance - mysql

Does $this->db->insert_batch(); insert with 1 table connection or does it insert each row separately incurring overhead of opening connections?

From the documentation of code igniter insert_batch do this kind of things
$data = array(
array(
'title' => 'My title' ,
'name' => 'My Name' ,
'date' => 'My date'
),
array(
'title' => 'Another title' ,
'name' => 'Another Name' ,
'date' => 'Another date'
)
);
$this->db->insert_batch('mytable', $data);
// Produces: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date'), ('Another title', 'Another name', 'Another date')
So it would produce only one query with all the values, normally this way faster then doing separate inserts.

To answer your question: It uses one connection.

Actually #RageZ answer based on document is not always correct. Because it's totally based on the number of items you want to insert. When looking at codeigniter insert_batch() code, you can see that they slice batch inserts into 100 items.
// Batch this baby (Around line number 1077 in codeigniter 2.x)
for ($i = 0, $total = count($this->ar_set); $i < $total; $i = $i + 100)
{
$sql = $this->_insert_batch($this->_protect_identifiers($table, TRUE, NULL, FALSE), $this->ar_keys, array_slice($this->ar_set, $i, 100));
//echo $sql;
$this->query($sql);
}
It means that your values will be slice to 100s inserts and if you uncomment the echo $sql part you can see what it's look like when you use insert batch for 101 items. So based on your connection preferences there can be more than one connection needed for inserting in db.

Related

Wordpresss - WP_query count

I need to count how many times my date recorded in the meta key:metakey_AMC_data, in format (d-m-Y) it is contained in the database by comparing it with the current date
$mostra_data_corrente = date('d-m-Y');
$query = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}postmeta
WHERE (meta_key = 'metakey_AMC_data'
AND meta_value = '$mostra_data_corrente')");
$conta_risultati = count($query);
and this I can do perfectly.but now my need is to execute the first query by linking another AND, and specify when the term slug is equal to the category of the event (terms taxonomy), obviously the query is incorrect
SELECT * FROM {$wpdb->prefix}postmeta
WHERE (meta_key = 'metakey_AMC_data'
AND meta_value = '$mostra_data_corrente')
AND(slug = 'aperitivi') "
how can i do this?
You can get that count as well. You need to modify query (code) like follow:
$qry = array(
'post_type' => 'post', // mention your post type to narrow down searching through postmeta table
'meta_query' => array(
array(
'meta_key' => 'metakey_AMC_data',
'meta_value' => $mostra_data_corrente,
'compare' => '='
)
),
'tax_query' => array(
array(
'taxonomy' => 'nameoftaxonomy', // Write the name of taxonomy that you have assinged while you created a CPT (custom post type)
'field' => 'slug',
'terms' => 'aperitivi',
)
)
)
$the_query = WP_Query($qry);
echo $the_query->post_count;
You have to make some necessary changes in above code to suite your requirements. I've added comment where you have to do changes.

Codeigniter database backup - Insert multiple rows without repeating “INSERT INTO”

I'm trying out to find a way to backup my database using Codeigniter "Database Utility" but without repeating “INSERT INTO”, I mean everything works perfectly, but when we see the generated sql file we see something like this:
INSERT INTO Membership (ID, FirstName, LastName, DOB)
VALUES (1, 'John', 'Smith', '5/5/1960')
INSERT INTO Membership (ID, FirstName, LastName, DOB)
VALUES (2, 'Hello", 'World", '4/9/1975')
INSERT INTO Account(ID, Type, Effective_Date, Status)
VALUES (1, 'Gold', GetDate(), 'Active')
INSERT INTO Account(ID, Type, Effective_Date, Status)
VALUES (2, 'Platinum', GetDate(), 'Inactive')
INSERT INTO Participant(ID, Code, Type)
VALUES (1, 002, 'A')
INSERT INTO Participant(ID, Code, Type)
VALUES (2, 002, 'A')
The which is so slow whenever we import in another database. I want to get something like this:
INSERT INTO #temp_table (1, 'John', 'Smith, '5/5/1960', 'Gold', 'Active', '002', 'A')
.
.
.
.
so on
using only one INSERT INTO, is there any way to achieve this? Thanks.
You can make use of CodeIgniter insert_batch() function
Follow this link here to see how it works:
Create a multi-dimensional array with field and values like this, and use codeigniter inset_batch() function to insert all these in a single query.
$data = array(
array(
'ID' => 1,
'FirstName' => 'John',
'LastName' => 'Doe',
'DOB' => '5/5/1960'
),
array(
'ID' => 2,
'FirstName' => 'John',
'LastName' => 'Smith',
'DOB' => '5/5/1960'
)
);
$this->db->insert_batch('temp_table', $data);
I understand your problem, Database Utility is quite slow also, due to string concatenation, if passthru() is enabled on your server, then mysqldump can be used, here is working code, which will export current database.
public function backup_current_db()
{
$db_user=$this->db->username;
$password=$this->db->password;
$db=$this->db->database;
$filename = $db . "-" . date("Y-m-d_H-i-s") . ".sql";
$mime = "application/octet-stream";
header( "Content-Type: " . $mime );
header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
$cmd = "mysqldump -u '$db_user' --password='$password' --no-create-info --complete-insert '$db' ";
passthru( $cmd );
die();
}

Optimizing a Wordpress Query

I'm working on a WordPress site with a large product database. I need to make a listing of all the products with a single taxonomy term exception. Using wp_query() creates a huge object and takes a long time. Also, for some reason, my arguments will not exclude products from the one taxonomy term I don't want listed. Here is my current query:
$args = array(
'post_type' => 'products',
'post_status' => 'publish',
'orderby' => 'post_title',
'numberposts' => -1,
'tax_query' => array(
'taxonomy' => 'product-main-cats',
'field' => 'term_id',
'terms' => array(23),
'operator' => 'NOT IN',
),
);
$prods = new WP_Query( $args );
I want to rewrite this query using the wpdb class so that I only fetch exactly what I need for my listing instead of the huge wp_query() object. The only columns I need from the wp_post table are, ID and post_title. I'm just not sure of the mySQL syntax, especially for excluding the posts related to the single taxonomy term. Can anyone help me rewrite this?
TIA!
You can write this query via $wpdb , I have attached a sql query version below of your WP_Query.
global $wpdb;
$results = $wpdb->get_results( "SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'products' AND ((wp_posts.post_status = 'publish')) ORDER BY wp_posts.post_title DESC", ARRAY_A );

how write orderByField query in cakephp 3

In sql, I have this query, It is working perfectly and order by given array in "order BY Field". But in cakephp it is not working.
SELECT * FROM users
WHERE users.Id IN (3,7,2,13)
ORDER BY FIELD(users.Id ,3,7,2,13)
I get the users in following order. which is perfect
user _id
3
7
2
13
Cakephp 3
$unique_user_id_list = (3,7,2,13);
$id_list = '3','7','2','13'; This is string.
$users = $this->Users->find('all',[
'contain' => [],
'conditions'=>['Id IN' => $unique_user_id_list],
'order BY FIELD'=>['Users.Id'=>$id_list]
]);
In this query, I get user in following order
user_id
2
3
7
13
I tried both following ways but no one work. Only "order" clause gives error while other one "order by field" gives no error but does not work as expected.
'order'=>['Users.Id'=>$id_list]
'order BY FIELD'=>['Users.Id'=>$id_list]
Any idea how to write above sql query in cakephp 3 to get it work.
Answer for this question
In short words 'order' => "FIELD(id, '2', '3', '7', '13')"
In detail first use loop to convert array in string.
$id_list;
foreach ($unique_user_id_list as $key => $value) {
if($check == 1){
$id_list = 'FIELD ( Id'.',' . "'". $value. "'";
$check =2;
}
else{
$id_list = $id_list . "," . "'". $value. "'";
}
}
$id_list = $id_list . ")";
above loop will generate "FIELD(id, '2', '3', '7', '13')"
Full query how I used it is given below.
$users = $this->Users->find('all',[
'contain' => [],
'conditions'=>['Id IN' => $unique_user_id_list],
'order'=> $id_list
]);
Try formatting the order statement as follows
->order(['users.Id'=>'ASC']);

Two prepared statements on one page - first works, second fails

I'm using MDB2 for prepared statements. I'm using the name-based example from the PEAR MDB2 site as a guide, and this is what I have so far:
$q = '
UPDATE
abc_news
SET
newstitle = :newstitle,
categoryid = :categoryid,
facilityid = :facilityid,
user_id_mod = :user_id_mod,
user_id_add = :user_id_add,
display = :display,
locked = :locked,
datemodified = NOW()
WHERE
newsid = :newsid
';
$types = array(
'text',
'integer',
'integer',
'integer',
'integer',
'integer',
'integer',
'integer',
);
$res = $mdb2_dbx->prepare($q, $types,MDB2_PREPARE_MANIP);
$data = array(
'newstitle' => $n_newstitle,
'categoryid' => $n_categoryid,
'facilityid' => $n_facilityid,
'display' => 1,
'locked' => 1,
'user_id_add' => $n_user_id_add,
'user_id_mod' => $n_user_id_mod,
'newsid' => $newsid,
);
$affected_rows = $statment->execute($data);
if (PEAR::isError($res))
die('error');
$statement->free();
$q = '
UPDATE
abc_news_text
SET
newstext = :newstext
WHERE
newsid = :newsid
';
$types = array(
'text',
'integer',
);
$statment = $mdb2_dbx->prepare($q, $types,MDB2_PREPARE_MANIP);
$data = array(
'newstext' => $n_newstext,
'newsid' => $newsid,
);
$affected_rows = $statment->execute($data);
if (PEAR::isError($res))
die('error');
$statement->free();
The first query works - an autoincremented $newsid is printed to the screen (it increases with each new submission).
Directly below, I get this error:
Fatal error: Call to undefined method MDB2_Error::execute() in news.php on line 160
Line 160 is the second $affected_rows = $statment->execute($data); line.
I'm freeing up the statement, and the syntax appears to be the same on both prepared statements.
What am I doing wrong here?
that is because You are getting an MDB2_ERROR object not a statement object. Your prepare() obviously didn't work and you are not checking for the success of the prepare() at all to know this.
Also, I am not sure how your first is working since you set the prepare result to $res variable instead of $statment. I also notice your variable name $statment has no e (not sure if this was a typo).