MySQL Optimizations using CodeIgniter Active Records with Multiple Databases - php

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.

Related

access two different databases on different servers in the same query

So far we have a server with 2 databases and a mysql user that accesses any of them. For example
`select * from magento.maintable, erp.maintable`
now our erp is very slow and we want to separate our database on another server, but we have hundreds (almost a thousand) sql queries that have access in the same query to the two databases, for example
`insert into magento.table
select * from erp.maintable`
or
select * from erp.maintable inner join magento.table...
and more and more
How can I make everything work the same without changing these queries? but with the databases on different servers
To access the databases I have created a class for each database and through an object I make the queries, insertions, updates and deletions, like this
` public function exec($query, $result_array = true)
{
$this->data->connect();
$result = $this->data->query($query, $result_array);
$this->data->disconnect();
return $result;
}`
all help is welcome, the point is to find an optimal way to do this and not have to manually change 1000 sql queries made by another programmer
To access more than one database server in one query, you either have to use FEDERATED database engine or use replication to replicate the ERP-data from another server to the original one.
The use of FEDERATED engine is likely to cause additional performance problems and the replication requires some work to set up.
If the sole reason for the new server is the performance in ERP, you might want to see why the ERP is slow and try to solve that (optimize, move both databases to a new server, etc). When you have both databases on the same server, the query optimizer is able to combine and make efficient use of indexes.

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

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

Two db connect files

I am using one db file to connect to the database. However, i need to show something else from another db database on this site. I can't use two db connect files. So, how do i go about display one websites content on another website with two different connections.
For one thing, you don't need separate database connections to the same server. Simply specify the database name before each table name in your SQL statements. For example:
SELECT foo, bar FROM db.table;
rather than:
SELECT foo, bar FROM table;
For another, you shouldn't be storing the database connection in a global for just the sort of reason you're running into. I suspect you're using the outdated mysql extension, which uses an implicit DB connection resource whenever one isn't explicit. Switch to PDO and create a simple connection manager class. One big advantage to PDO is it supports prepared statements, which can be safer and more performant than what the mysql extension provides. If you need a PDO tutorial, try "Writing MySQL Scripts with PHP and PDO"
If it is a separate db server you might need to look into the mysql federated engine which allows you to link to databases on separate servers as if they were on the same host.

Possible to have drupal read from a sql database?

I have a site under drupal (using mysql) but need it to read from a external sql database and make quires/reports, maybe using views2?
Is is at all possible? I been looking for a solution to just read (not import, its thousands of entries...) from an external database for hours and not sure if its even possible.
Drupal can access external databases, assuming that they are one of the types Drupal supports.
I will refer you to this handbook page: How to connect to multiple databases within Drupal.
However, to actually access data in the external database, you will need to write custom code, probably in a custom module. Essentially, you will need to do something like:
// Set Database API to use the other database.
db_set_active('external_db');
// Query the database.
db_query("SELECT * FROM {your_table} WHERE condition = 'value'");
// Set the Database API back to the default db.
db_set_active('default');
Essentially, point the database to the external database, make your reads and writes, and switch back. If you forget to switch back, Drupal will crash as it's core functions will try to work with the non-Drupal database.
It's possible to define several database connections in your settings.php and use db_set_active to select which database to use.
If you want to do this with views, you might need to do some extra work and embed the view after setting the active database to the external one.
Without writing code, you should be able to create views of the secondary database using the Table Wizard module. However, given how Drupal 6 handles its database abstraction, this will require that the secondary database be the same type as the main Drupal database (eg, either both are MySQL or both are Postgresql).

How quick is switching DBs with PHP + MySQL?

I'm wondering how slow it's going to be switching between 2 databases on every call of every page of a site. The site has many different databases for different clients, along with a "global" database that is used for some general settings. I'm wondering if there would be much time added for the execution of each script if it has to connect to the database, select a DB, do a query or 2, switch to another DB and then complete the page generation. I could also have the data repeated in each DB, I just need to mantain it (will only change when upgrading).
So, in the end, how fast is mysql_select_db()?
Edit: Yes, I could connect to each DB separately, but as this is often the slowest part of any PHP script, I'd like to avoid this, especially since it's on every page. (It's slow because PHP has to do some kind of address resolution (be it an IP or host name) and then MySQL has to check the login parameters both times.)
Assuming that both databases are on the same machine, you don't need to do the mysql_select_db. You can just specify the database in the queries. For example;
SELECT * FROM db1.table1;
You could also open two connections and use the DB object that is returned from the connect call and use those two objects to select the databases and pass into all of the calls. The database connection is an optional parameter on all of the mysql db calls, just check the docs.
You're asking two quite different questions.
Connecting to multiple database instances
Switching default database schemas.
MySQL is known to have quite fast connection setup time; making two mysql_connect() calls to different servers is barely more expensive than one.
The call mysql_select_db() is exactly the same as the USE statement and simply changes the default database schema for unqualified table references.
Be careful with your use of the term 'database' around MySQL: it has two different meanings.

Categories