spotorm / spot2

Spot v2.x DataMapper built on top of Doctrine's Database Abstraction Layer
http://phpdatamapper.com
BSD 3-Clause "New" or "Revised" License
601 stars 101 forks source link

Performance is bad on Collection queries #144

Open nebulousGirl opened 9 years ago

nebulousGirl commented 9 years ago

On my dev computer, when I attempt to retrieve a fairly complex entity (20 fields and 5 relations) collection, it takes 130ms to load ~60 entities. Each entity takes 2-3 ms to instantiate and prepare.

When I comment the relations, it takes 100ms.

One of the biggest hits seems to be with $this->data($data, false); in the Entity class constructor. When I change it for $this->_data = $data; and keep relations, it takes 60ms. Without relations nor data(), I get ~30ms.

Is this the performance to expect or am I doing something wrong?

$result = $mapper->all();
foreach ($result as $entity) {
    //...
}
vlucas commented 9 years ago

I honestly have not done any performance benchmarking, but now that this project is getting a good amount of users, it might be a good time to start. Thanks for opening this issue and investigating this a bit. Performance improvements help all users immediately.

alejosv commented 5 years ago

@vlucas why if Doctrine allow specific fields in your select function Spot it does not allow it?.

Select on Doctrine:

public function select($select = null)
{
    $this->type = self::SELECT;
    if (empty($select)) {
        return $this;
    }
    $selects = is_array($select) ? $select : func_get_args();
    return $this->add('select', new Expr\Select($selects), false);
}

If Spot built on top of Doctrine, is only send the fields as params and allow function of select on Spot get params, something like this:

$result = $mapper->select('field1, field2');
vlucas commented 5 years ago

This is supported in the Query object: https://github.com/spotorm/spot2/blob/master/lib/Query.php#L201

So from the mapper, you would have to do something like this:

$result = $mapper->all()->select('field1, field2');

Remember that Spot lazy-executes query objects, so you can add more criteria even after calling all() before the query actually gets executed.

FlipEverything commented 5 years ago

Wow, I did not know that.