codeigniter insert from query how to optimized - codeigniter

I want to optimized my query on codeigniter.
this query works but it seems, its take time to insert the result to my database table.
$this->db->select('client_id');
$this->db->from('event');
$query = $this->db->get();
foreach($query->result_array() as $row){
$client_id = $row['client_id'];
$data = array( 'event_id' => $event_id , 'client_id' => $client_id);
$this->db->insert('event_entry', $data);
}
I would like to know if theres a way it to optimized.

Instead of doing n number of inserts, doing just a single insert should improve execution time. You can achieve this in codeigniters active record by using insert_batch() .
$this->db->select('client_id');
$this->db->from('event');
$query = $this->db->get();
$data = array();
foreach($query->result_array() as $row){
$client_id = $row['client_id'];
array_push($data, array('event_id' => $event_id , 'client_id' => $client_id));
}
$this->db->insert_batch('event_entry', $data);
Produces:
INSERT INTO event_entry (event_id, client_id) VALUES ('event_id', 'client_id'), ('event_id', 'client_id'), ...

Replace all of that code with:
$this->db->query("
INSERT INTO event_entry (event_id, client_id)
SELECT ?, client_id
FROM event
", array($event_id));
And you will clearly notice the difference in execution time :) Plus in my opinion, having less code to worry about.
This query can't be run from Active Records, but it should be quite self explaining. Just like a normal SELECT, if fetches client_id and the already defined value $event_id by each event row. It then takes these values, and INSERT them into event_entry.
Note that ? and array($event_id) insert the value into the query escaped (and safe). Never insert into query as SELECT {$event_id}, client_id unless you know what you're doing.
Jeemusu's solution is indeed a nice way to do it through Active Records, but if it's performance you want all the way, one query is faster than two in this case.

you can use insert_batch command to insert data to database . Produce your data array with foreach loop and then use insert_batch database.http://ellislab.com/codeigniter/user-guide/database/active_record.html
please let me know if you need any help

Related

Codeigniter Query binding multiple fields with the same value

I'm in a situation where I'm doing a MySQL query with Codeigniter and where I have a lot of fields value request which are ALL the same.
Example:
$this->db->query('SELECT * FROM abc WHERE user_id = ? AND msg_from = ? AND msg_to != ?', [$id, $id, $id]);
This has just 3 question marks but the query I'm working on is HUGE and has 19 question marks WHICH ARE ALL THE SAME variable.
So I was trying to figure out how to tell Codeigniter all question marks are pointing to the same variable without having to fill an array with 19 times the same variable.
I thought of a for-loop but I wanted to know if a shortcut exist.
you should be able to do this with Codeigniters Query Builder pretty easily
Something like that should work:
$this->db
->select('*')
->from('abc');
$arrFields = array('users_id', 'msg_from', 'msg_to');
foreach($arrFields AS $val)
{
$this->db->where($val, $id);
}
$query = $this->db->get();

Updating multiple tables in codeigniter

I have a function in codeigniter that i want to use to update two tables. This is the code
if($loss_making_trade_amount > 5 && $loss_making_trade_amount < 20){
$user_data = array(
'trading_balance' => $trading_balance_float - 0.50
);
$data = array(
'trade_consequence' => '0.50',
'loss_in_amounts_cron_status' => 'seen'
);
$where = "id='$rid'";
$where_trading_balance = "email='$email'";
$this->db->where($where);
$this->db->set($data);
$this->db->update('mailbox_ke_01', $data);
//update users table at this level
$this->db->where($where_trading_balance);
$this->db->set($user_data);
$this->db->update('users', $user_data);
}
Will i be able to update the tables in the way i have done or will $this be pointing to the first table when updating the second table?.
Your code looks fine, once a query ran - you don't have to be worry about because the Query Builder resets itself after every query if it is finished - or dies in case of a DB Error.
You can take a closer look here
The documentation also clearly suggests that the query runs if the update function gets called.
$this->db->update() generates an update string and runs the query based on the data you supply.
For more information read the documentation here
The only thing i would change are your where clauses:
instead of
$where = "id='$rid'";
$this->db->where($where);
you should use the where function of the Querybuilder properly
$this->db->where("id", $rid);
The same applies for your $where_trading_balance

Yii2 subquery GROUP BY in active record

can I convert this query
"SELECT * FROM (SELECT * FROM blog_post ORDER BY data DESC) blog_post GROUP BY blog_id LIMIT 2"
into a Yii2 active record query?
Thx
Ms
Yes, you can do this.
Yii2 gave us a wonderful library support.
You can form custom sql query and pass this query in findBySql() like:
$sql = "Some query/nested query";
$result = ModelClass::findBySql($sql);
Visit Yii official documentation.
BlogPost::find()
->orderBy('data DESC')
->groupBy('blog_id')
->limit(2)
->all();
I suppose you can do in this way :
Ⅰ:create a subQuery where you select from.
$blogPostQuery = BlogPostModel::find()->orderBy(['data' => SORT_DESC]);
Ⅱ:Get activeRecord results. The from params is an exist Query.
$models = (new yii\db\Query)
->from(['blog_post ' => $blogPostQuery])
->groupBy(['blog_id'])
->limit(2)
->all();
ps:
see yii\db\query->from()-detail in Yii Api;
(public $this from ( $tables )) $tables can be either a string (e.g. 'user') or an array (e.g. ['user', 'profile']) specifying one or several table names··· or a sub-query or DB expression
Have a try!I hope it`s useful for you:))

Can I run a CodeIgniter database query without clearing it from the class?

I am using the CodeIgniter database class to generate results and then use the pagination class to navigation through them. I have a model that retrieves member results from the table. I would like to calculate the total number of rows from the query so I can pass this to the pagination class. The count_all db helper function won't suffice because that doesn't take in account any "where" or "join" clauses that I include.
If this is my query:
$this->db->select('m.user_id AS id, m.email_address, m.display_name, m.status, UNIX_TIMESTAMP(m.join_date) AS join_date,
l.listing_id, COUNT(l.member_id) AS total_listings,
g.group_id AS group_id, g.title AS group_title')
->from('users AS m')
->join('listings AS l', 'm.user_id = l.member_id', 'left')
->join('groups AS g', 'm.group_id = g.group_id', 'left')
->group_by('m.user_id');
How can I continue to use this query if I wanted to do something like this:
if($query_total = $this->db->get()){
$this->total_results = $query_total->num_rows();
}
$this->db->limit($limit, $offset);
if($query_members = $this->db->get()){
return $query_members->result_array();
}
Update: In other words, I want to run a query with the get() method without clearing it from the query builder when it's done running so I can use the top part of the query later.
You can get it by using Active Record Caching (the last category on that page).
$this->db->start_cache(); // start caching
$this->db->select('m.user_id AS id, m.email_address, m.display_name, m.status, UNIX_TIMESTAMP(m.join_date) AS join_date,
l.listing_id, COUNT(l.member_id) AS total_listings,
g.group_id AS group_id, g.title AS group_title')
->from('users AS m')
->join('listings AS l', 'm.user_id = l.member_id', 'left')
->join('groups AS g', 'm.group_id = g.group_id', 'left')
->group_by('m.user_id');
$this->db->stop_cache(); // stop caching
Then you can use that query as much as you want.
if($query_total = $this->db->get()){
$this->total_results = $query_total->num_rows();
}
$this->db->limit($limit, $offset);
if($query_members = $this->db->get()){
return $query_members->result_array();
}
You can also flush the cache when you don't want that cached query anymore.
$this->db->flush_cache();
Hope it will be useful for you.
You are not passing any table name in $this->db->get() function.
Thank you

Return new id with DB::insert() in Laravel 4

In Laravel 4, when you perform a DB::insert(), how can you get the ID of the row that has just been inserted? Similar what we have with the function ->insertGetId(). Reason for using DB::insert() is that its a complex PostgreSQL query that cannot be built using Fluent.
Example Query:
$newId = DB::insert('insert into users (id, name) values (?, ?)', array(1, 'Dayle'));
echo $newId; // returns 1
There is a insertGetId method.
$id = DB::table('users')->insertGetId(
array('id' => 1, 'name' => 'Dayle Rees')
);
If you take a look at Illuminate\Database\ConnectionInterface you can see how these functions are written. Unfortunately DB::insert() returns a boolean from PDOStatement::execute() and there is no DB::insertGetId() at the moment. If this would be useful then you should request it on GitHub.
In the mean time, you should be able to use DB::getPdo()->lastInsertId()
There is a insertGetId() method, as follows:
$dataset = array('column_id' => 1, 'name' => 'Dayle');
$column_id = DB::table('users')->insertGetId($dataset,'column_id');
A bit late with the answer but, I think for psql it's best to use native RETURNING id
The query that worked for me was:
DB::select(
DB::raw('insert into threads (created_at, updated_at) values (?, ?)
returning id'), [Carbon::now(), Carbon::now()]
);
If you get in complex structure, better to use Eloquent.
Best thing that you need review docs :
http://laravel.com/docs/eloquent
After saving the data into the DB you just call $insertedId = $user->id; where $user->save() is called before the step.
more info here

Resources