CodeIgniter - only connect to database if there is a query to run - php

At the moment I load the database class in my autoload which automatically creates a connection to mysql. If there are no queries it will have still created a connection.
For performance I only want to connect to mysql if a query has been run.
What would be the best way to achieve this?
I am thinking of writing a model function that all queries run through which detects if the database has been connected to or not, and simply calls $this->load->database() if not before running $this->db->query().
The problem with this is that I would have to change all of my $this->db->query() references in my code which is a pain.
Ideally I would like to extend the $this->db->query() function to support this.
Any ideas?

You can modify the autoinit property of your database config
$db['mydb']['autoinit'] = false;
This will cause you database class to not initialize (which include connecting to the server) when instantiated, it will instead happen when the first query occurs.
See the database configuration page

Related

Run a query each time a database connection is opended Zend FM

Is it possible to execute a query every time a new connection to the database is open. This query needs to be run immediately after opening a database connection because this query calls a stored procedure that sets up various access control on the tables using the details of the user who requested to run the query. I have tried to call this stored procedure in various places and they are all successful but I would like some feedback.
I have put this query in an abstract mapper class which other mappers extend. Each time a new mapper is instantiated the stored procedure is called.
Another place to put this call to the stored procedure is before calls to other mapper methods. The downside of this is that there will a lot of duplicate code (code that calls the stored procedure).
The final place to put this call is in Bootstrap.php. Each _init method in this file is suppose to run only once each time the application is loaded. I have decided to put this call to the stored procedure in one of the Bootstrap.php for one of our modules. This is so far the best place I can think of because I only have to write the code that calls the stored procedure once and each time the application is accessed the initialize method will run. The downside of this is that I do not know the side affects of putting things in Bootstrap.php.
One of the main downsides of all these places is that the stored procedure gets called many times. For the access control to work, the stored procedure needs to be called only once per database session. This will not cause any issue other than speed due to unnecessary calls.
Are there any better places to put this call to the stored procedure? Does Zend FM have this feature implemented somewhere? Is there anything I need to take into consideration if I put this in the Bootstrap file.
Thanks for reading this and any help provided.
DB2 Version 10.5
Linux Platform
Zend FM Version 2
As an alternative, you can configure this on the database side by setting the database configuration parameter connect_proc to the name of your stored procedure. Note that the procedure will then be called for all connections, remote and local, including those made by the database administrator.
If you need to pass extra information from the client to the connect_proc routine, you could use the client accounting string connection parameter, which you could then read in the procedure using the MON_GET_CONNECTION() function:
SET acct_string = (
SELECT client_acctng FROM TABLE (
MON_GET_CONNECTION(MON_GET_APPLICATION_HANDLE(),-1)
)
)

Unused write database connections

This issue was raised using Laravel 5.0.
My project's database setup consists of 1 write node and multiple read-replicas (postgresql). Everytime a connection is initiated for any query, eg:
php
<?php $user = \App\User::find(1); ?>
... a connection is made to the write node. This occurs even when no writing queries are run (including set names 'utf8', etc); a connection will be set up, but all the SELECT queries are run correctly on the read-replicas.
How can I avoid this write connection if I don't need/use it for read-only requests?
There are two classes maintaining the DB connections: Illuminate/Database/DatabaseManager and Illuminate/Database/Connectors/ConnectionFactory.
When any Laravel class want to use a DB connection, it makes a call to DatabaseManager::connection(), which eventually request for an actual connection via ConnectionFactory::make().
Your issue lies here, the underlying of make() process creates both 'read' and 'write' connections at the same time. So 'write' connection is always established. It is a behavior of ConnectionFactory.
So the best way is opening an issue on Laravel asking the dev team whether they would like to improve the connection establishment only when it is actually needed.
Edited:
I just found that you already opened an issue :-)
https://github.com/laravel/framework/issues/10337

Where does codeigniter create and destroy mysql connection and is the db class singleton?

If we have multiple database groups in database.php:-
1) Do the connections of all of them are made even only one has to be used in a particular call. ie. if i have database groups a,b
And in my call i load model that is loading only group b.
2) If i have loaded two models in my controller and if both of them are loading same databases, would different connection will be made or same connection will be shared.
Ex:- controller mycont.php has following:-
$this->load->model('model1');
$this->load->model('model2');
If both model1.php and model2.php has following:-
$this->load->db('connection_name');
3) Where are the connections closed.
Ex:- If i have following code:-
$this->databaseFunc();//completes the database work nothing required after this
here a curl call is made which takes long time
So when does database connection is closed, after curl or it gets closed itself on over exceeding mysql_wait_time configuration at mysql server.
Hope the answer to this question will prove useful for understanding DB with codeigniter in a better way.
In CI, each library is a singleton. It is created on load->library and destroyed at the end of the request.
The database lib handle database connection, so the connection is closed when the library is destroyed. It has nothing to do with curl.
I've never tryed it but it should work like that.

Force MySQL to write back

I have an issue where an instance of Solr is querying my MySQL database to refresh its index immediately after an update is made to that database, but the Solr query is not seeing the change made immediately prior.
I imagine the problem has to be something like Solr is using a different database connection, and somehow the change is not being "committed" (I'm not using transactions, just a call to mysql_query) before the other connection can see it. If I throw a sufficiently long sleep() call in there, it works most of the time, but obviously this is not acceptable.
Is there a PHP or MySQL function that I can call to force a write/update/flush of the database before continuing?
You might make Solr use SET TRANSACTION ISOLATION LEVEL = READ-COMMITTED to get more prompt view of updated data.
You should be able to do this with the transactionIsolation property of the JDBC URL.

MySQL Optimizations using CodeIgniter Active Records with Multiple Databases

I am using multiple databases using CodeIgniter Active Records class. I had to disable persistent connection with MySQL, because CodeIgniter Active Records class can't make persistent connections using multiple databases.
I am looking at the load of my database, it seems like it's using most of it's queries calling "change database" and I am not sure if that's a good sign.
How can I optimize this without having to call "change database" all the time?
It's not as user friendly as most of the Active Record commands, but you can call the SQL directly like this:
$query = $this->db->query("SELECT * FROM database_a.some_table");
$query2 = $this->db->query("SELECT * FROM database_b.another_table");
Are you using queries that reference both databases? If not, it's not too difficult to load a new DB instance for the second database. I.e. you'd still use $this->db for the first, but you could have $this->db2 for the second. I honestly have no idea if that would trigger the "change database" command you're talking about, but it would be MUCH more sustainable code, at least. CI could keep its connections to each database open for the duration of the script (not a persistent connection), and it seems your problem would be fixed.
I've never needed multiple mysql databases in a single app, so this is entirely a guess based on what I've seen with, say, one mysql db and another being an sqlite db.

Categories