Lazy initialization
For collection elements
Subselect fetching
Doctrine knows how to fetch collections efficiently using a subselect.
Executing SQL statements later, when needed
The connection never issues an INSERT or UPDATE until it is actually needed. So if an exception occurs and you need to abort the transaction, some statements will never actually be issued. Furthermore, this keeps lock times in the database as short as possible (from the late UPDATE to the transaction end).
Join fetching
Doctrine knows how to fetch complex object graphs using joins and subselects
Multiple collection fetching strategies
Doctrine has multiple collection fetching strategies for performance tuning.
Dynamic mixing of fetching strategies
Fetching strategies can be mixed and for example users can be fetched in a batch collection while
users' phonenumbers are loaded in offset collection using only one query.
Driver specific optimizations
Doctrine knows things like bulk-insert on mysql
Transactional single-shot delete
Doctrine knows how to gather all the primary keys of the pending objects in delete list and performs only one sql delete statement per table.
Updating only the modified columns.
Doctrine always knows which columns have been changed.
Never inserting/updating unmodified objects.
Doctrine knows if the the state of the record has changed.
PDO for database abstraction
PDO is by far the fastest availible database abstraction layer for php.