Skip to content
Browse files

doctrine1-documentation-24 Edit improving-performance.rst

  • Loading branch information...
1 parent 2b36a35 commit d7cdf657a402a9e75de9759347d76fc278f71caa @jeserkin jeserkin committed
Showing with 102 additions and 65 deletions.
  1. +102 −65 source/en/manual/improving-performance.rst
View
167 source/en/manual/improving-performance.rst
@@ -34,18 +34,20 @@ Doctrine root by the name :file:`Doctrine.compiled.php`.
Compiling is a method for making a single file of most used doctrine runtime
components including the compiled file instead of multiple files (in worst
cases dozens of files) can improve performance by an order of magnitude. In
-cases where this might fail, a :php:exc:`Doctrine_Exception` is throw detailing the
+cases where this might fail, a :php:class:`Doctrine_Exception` is throw detailing the
error.
Lets create a compile script named :file:`compile.php` to handle the
-compiling of Doctrine::
+compiling of DoctrineL:
+
+::
// compile.php
- require_once('/path/to/doctrine/lib/Doctrine.php');
- spl_autoload_register(array('Doctrine', 'autoload'));
+ require_once( '/path/to/doctrine/lib/Doctrine.php' );
+ spl_autoload_register( array( 'Doctrine', 'autoload' ) );
- Doctrine_Core::compile('Doctrine.compiled.php');
+ Doctrine_Core::compile( 'Doctrine.compiled.php' );
Now we can execute :file:`compile.php` and a file named
:file:`Doctrine.compiled.php` will be generated in the root of your
@@ -53,21 +55,30 @@ Now we can execute :file:`compile.php` and a file named
.. code-block:: sh
- php compile.php
+ $ php compile.php
If you wish to only compile in the database drivers you are using you
can pass an array of drivers as the second argument to :php:meth:`compile`.
For this example we are only using MySQL so lets tell Doctrine to only
-compile the ``mysql`` driver::
+compile the ``mysql`` driver:
+
+::
+
+ // compile.php
// ...
- Doctrine_Core::compile('Doctrine.compiled.php', array('mysql'));
+ Doctrine_Core::compile( 'Doctrine.compiled.php', array( 'mysql' ) );
Now you can change your :file:`bootstrap.php` script to include the compiled
-Doctrine::
+Doctrine:
+
+::
+ // bootstrap.php
+
+ // ...
+ require_once( 'Doctrine.compiled.php' );
// ...
- require_once('Doctrine.compiled.php');
=====================
Conservative Fetching
@@ -78,9 +89,11 @@ actually need. This may sound trivial but laziness or lack of knowledge about
the possibilities that are available often lead to a lot of unnecessary
overhead.
-Take a look at this example::
+Take a look at this example:
+
+::
- $record = $table->find($id);
+ $record = $table->find( $id );
How often do you find yourself writing code like that? It's convenient but it's
very often not what you need. The example above will pull all columns of the
@@ -92,7 +105,9 @@ I'm sure you all know why a query like the following is not ideal:
.. code-block:: sql
- SELECT * FROM my_table
+ SELECT
+ *
+ FROM my_table
The above is bad in any application and this is also true when using Doctrine.
In fact it's even worse when using Doctrine because populating objects with
@@ -108,48 +123,54 @@ structures you can use in PHP. Objects have the most value when they're used
to accomplish complex business logic. It's a waste of resources when data gets
wrapped in costly object structures when you have no benefit of that. Take a
look at the following code that fetches all comments with some related data for
-an article, passing them to the view for display afterwards::
+an article, passing them to the view for display afterwards:
+
+::
$q = Doctrine_Query::create()
- ->select('b.title, b.author, b.created_at')
- ->addSelect('COUNT(t.id) as num_comments')
- ->from('BlogPost b')
- ->leftJoin('b.Comments c')
- ->where('b.id = ?')
- ->orderBy('b.created_at DESC');
+ ->select( 'b.title, b.author, b.created_at' )
+ ->addSelect( 'COUNT(t.id) as num_comments' )
+ ->from( 'BlogPost b' )
+ ->leftJoin( 'b.Comments c' )
+ ->where( 'b.id = ?' )
+ ->orderBy( 'b.created_at DESC' );
- $blogPosts = $q->execute(array(1));
+ $blogPosts = $q->execute( array( 1 ) );
Now imagine you have a view or template that renders the most recent
blog posts:
.. code-block:: html+php
- <?php foreach ($blogPosts as $blogPost): ?>
- <li>
- <strong>
- <?php echo $blogPost['title'] ?>
- </strong>
+ <?php foreach ( $blogPosts as $blogPost ): ?>
+ <li>
+ <strong>
+ <?php echo $blogPost['title'] ?>
+ </strong>
- - Posted on <?php echo $blogPost['created_at'] ?>
- by <?php echo $blogPost['author'] ?>.
+ - Posted on <?php echo $blogPost['created_at'] ?>
+ by <?php echo $blogPost['author'] ?>.
- <small>
- (<?php echo $blogPost['num_comments'] ?>)
- </small>
- </li>
+ <small>
+ (<?php echo $blogPost['num_comments'] ?>)
+ </small>
+ </li>
<?php endforeach; ?>
Can you think of any benefit of having objects in the view instead of
arrays? You're not going to execute business logic in the view, are you?
-One parameter can save you a lot of unnecessary processing::
+One parameter can save you a lot of unnecessary processing:
+
+::
- $blogPosts = $q->execute(array(1), Doctrine_Core::HYDRATE_ARRAY);
+ $blogPosts = $q->execute( array( 1 ), Doctrine_Core::HYDRATE_ARRAY );
-If you prefer you can also use the :php:meth:`setHydrationMethod` method::
+If you prefer you can also use the :php:meth:`setHydrationMethod` method:
- $q->setHydrationMode(Doctrine_Core::HYDRATE_ARRAY);
- $blogPosts = $q->execute(array(1));
+::
+
+ $q->setHydrationMode( Doctrine_Core::HYDRATE_ARRAY );
+ $blogPosts = $q->execute( array( 1 ) );
The above code will hydrate the data into arrays instead of objects
which is much less expensive.
@@ -157,27 +178,33 @@ which is much less expensive.
.. note::
One great thing about array hydration is that if you use the
- ``ArrayAccess`` on your objects you can easily switch your queries to use
+ :php:class:`ArrayAccess` on your objects you can easily switch your queries to use
array hydration and your code will work exactly the same. For example the
above code we wrote to render the list of the most recent blog posts would
work when we switch the query behind it to array hydration.
Sometimes, you may want the direct output from PDO instead of an object or an
array. To do this, set the hydration mode to
-:php:const:`Doctrine_Core::HYDRATE_NONE`. Here's an example::
+:php:const:`Doctrine_Core::HYDRATE_NONE`. Here's an example:
+
+::
$q = Doctrine_Query::create()
- ->select('SUM(d.amount)')
- ->from('Donation d');
+ ->select( 'SUM(d.amount)' )
+ ->from( 'Donation d' );
- $results = $q->execute(array(), Doctrine_Core::HYDRATE_NONE);
+ $results = $q->execute( array(), Doctrine_Core::HYDRATE_NONE );
You will need to print the results and find the value in the array
-depending on your DQL query::
+depending on your DQL query:
+
+::
- print_r($results);
+ print_r( $results );
-In this example the result would be accessible with the following code::
+In this example the result would be accessible with the following code:
+
+::
$total = $results[0][1];
@@ -238,31 +265,40 @@ reference chains. Doctrine provides a :php:meth:`free` function on
:php:class:`Doctrine_Query` which eliminates the circular references on those
objects, freeing them up for garbage collection. Usage might look like:
-Free objects when mass inserting records::
+Free objects when mass inserting records:
+
+::
- for ($i = 0; $i < 1000; $i++) {
+ for ( $i = 0; $i < 1000; $i++ )
+ {
$object = createBigObject();
$object->save();
- $object->free(true);
+ $object->free( true );
}
-You can also free query objects in the same way::
+You can also free query objects in the same way:
- for ($i = 0; $i < 1000; $i++) {
+::
+
+ for ( $i = 0; $i < 1000; $i++ )
+ {
$q = Doctrine_Query::create()
- ->from('User u');
+ ->from( 'User u' );
$results = $q->fetchArray();
$q->free();
}
Or even better if you can reuse the same query object for each query in
-the loop that would be ideal::
+the loop that would be ideal:
+
+::
$q = Doctrine_Query::create()
- ->from('User u');
+ ->from('User u');
- for ($i = 0; $i < 1000; $i++) {
+ for ( $i = 0; $i < 1000; $i++ )
+ {
$results = $q->fetchArray();
$q->free();
}
@@ -275,7 +311,7 @@ Other Tips
There are two possible ways when it comes to using DQL. The first one is
writing the plain DQL queries and passing them to
- ``Doctrine_Connection::query($dql)``. The second one is to use a
+ ``Doctrine_Connection::query( $dql )``. The second one is to use a
:php:class:`Doctrine_Query` object and its fluent interface. The latter should
be preferred for all but very simple queries. The reason is that using the
:php:class:`Doctrine_Query` object and it's methods makes the life of the DQL
@@ -288,12 +324,11 @@ Other Tips
.. note::
- The following example assumes a many-many between ``Role``
- and ``User``.
+ The following example assumes a many-many between ``Role`` and ``User``.
::
- $role = new Role();
+ $role = new Role();
$role->name = 'New Role Name';
$user->Roles[] = $newRole;
@@ -303,12 +338,14 @@ Other Tips
The above code will load all roles of the user from the
database if they're not yet loaded! Just to add one new link!
- The following is the recommended way instead::
+ The following is the recommended way instead:
+
+ ::
- $userRole = new UserRole();
- $userRole->role_id = $role_id;
- $userRole->user_id = $user_id;
- $userRole->save();
+ $userRole = new UserRole();
+ $userRole->role_id = $role_id;
+ $userRole->user_id = $user_id;
+ $userRole->save();
==========
Conclusion
@@ -317,5 +354,5 @@ Conclusion
Lots of methods exist for improving performance in Doctrine. It is highly
recommended that you consider some of the methods described above.
-Now lets move on to learn about some of the :doc:`technology <technology>`
-used in Doctrine.
+Now lets move on to learn about some of the :doc:`technology`
+used in Doctrine.

0 comments on commit d7cdf65

Please sign in to comment.
Something went wrong with that request. Please try again.