Bad performance of Model::factory method
stefanreimers opened this issue · comments
I am facing a performance issue with one of my projects using paris/idiorm. All calls to DB are slow and a simple PDO usecase with the same queries show good performance.
I tracked down the bottleneck and found out that the Model::factory('model_name') call - without any further additions like WHERE clauses or even without executing the query - takes almost 90% of the time spent (approx. 1 second). Executing the query works like charm in a blink of an eye.
For testing purposes I removed all logic from the model and parameterized ORM logging on and off with no effect. Is there any way to speed up the factory() call - maybe some parameters to disable some overhead?
Some additional info:
Working on localhost, MySQL 5.5.27, PHP 5.4.7, Paris & Idiorm have been updated today to it's latest versions.
Thanks!
I have not seen this before. Do you have the actual code that is causing this issue available? It would be good to see where your doing your timing calls etc.
The code is pretty simple. First of all, the DB parameters like username and password are set along with the logging:
//ORM configuration
ORM::configure('mysql:host=localhost;dbname=mydbname');
ORM::configure('username', 'myname');
ORM::configure('password', 'mypass');
ORM::configure('logging', true);
Then:
/* Build query */
$debug['b'] = microtime();
require_once ('models/Bookmark.php');
$debug['c'] = microtime();
$bms = Model::factory('Bookmark');
$debug['c2'] = microtime();
$bms->where('account_id', $id );
$debug['c3'] = microtime();
// Add query if defined
if( !empty( $query ) ){
$bms->where_like( 'address', '%'.$query.'%' );
}
$debug['d'] = microtime();
$bms = $bms->order_by_expr('created_on DESC')->find_many();
$debug['e'] = microtime();
Printing the $debug
array shows significant amount of time spent between C and C2.
The Bookmark
class is stripped down to a basic version:
<?php
class Bookmark extends Model { }
?>
By the way: I use Slim Framework with Idiorm and Paris. But as my alternative PDO test class shows, the Slim Framework does not cause any measureable delay.
Thanks!
I uploaded a stripped down version to Google Drive
link removed
The DB credentials can be found in index.php; the SQL to create the table is saved in sql.txt
The output of above code is (a variation)
Array
(
[b] => 0.98459800 1405870848
[c] => 0.98587000 1405870848
[c2] => 0.99334500 1405870849
[c3] => 0.99351200 1405870849
[d] => 0.99352600 1405870849
[e] => 0.99926500 1405870849
)
Have you tried this code in isolation? I have not encountered this
anywhere. Can you try running the code against a fresh DB and outside of
any adapters or bridges and frameworks. It is really bizarre to me that it
would come from this method as it's not even very intensive.
On Jul 20, 2014 4:45 PM, "Stefan Reimers" notifications@github.com wrote:
I uploaded a stripped down version to
https://drive.google.com/folderview?id=0B3XbBGENeIZyVGlweUxaQkw3TzA&usp=sharing
(will be available for some time)The DB credentials can be found in index.php; the SQL to create the table
is saved in sql.txt
The output of above code is (a variation)Array
(
[b] => 0.98459800 1405870848
[c] => 0.98587000 1405870848
[c2] => 0.99334500 1405870849
[c3] => 0.99351200 1405870849
[d] => 0.99352600 1405870849
[e] => 0.99926500 1405870849
)—
Reply to this email directly or view it on GitHub
#98 (comment).
I added more debugging calls and tracked down the problem to the PDO instantiation in Idiorms _setup_db method. As this is exactly what my PDO test class is doing (which does not suffer from delays) I then applied the driver_options to the Idiorm/Paris configuration, which solved my problem:
ORM::configure('driver_options', array( PDO::ATTR_PERSISTENT => true ));
As a conclusion: The ORM Wrapper does not cause the delays but somehow my DB does while establishing a connection. Persistent connections do the trick for me.
Thank you for the update!