Search code examples
phpsqljoinphalcontable-relationships

PHP (Phalcon Framework) and MySQL: Models Relationships vs JOIN


For example there are 3 tables:

  • products
  • product_images
  • product_specs

And there are one-to-one relationships in models of this 3 tables.

By showing 50 products on page - it get more +2 extra queries inside cycle, so in total there are 150 rows and cool object:

$products = Products::find();
foreach ($products as $product)
{
    $product->name;
    $product->images->filename;
    $product->specs->volume;
}

Or just create custom method in Products Model and JOIN all necessary tables:

$products = Products::getComplete();
foreach ($products as $product)
{
    $product->name;
    $product->imageFile;
    $product->specVolume;
}

So, i'm wondering: is 1st practice is useful and don't make high load on MySQL daemon or slowing drastically php script execution time?


Solution

  • Answer to your first question: that practice could be useful, but would depend on your exact implementation.

    But, you are right. Using built-in one-to-one relationship will query the related model each time it's referenced which is intensive. So:

    $products->images
    

    is a new query for each record.

    Fortunately, there is a better, more efficient way that achieves the same result - PHQL.

    Since a one-to-one is basically a joined table that is called up via a second query (when it really doesn't need to), you could accomplish the same thing by doing something like:

    $products =
        (new \Phalcon\Mvc\Model)
            ->getModelsManager()
            ->executeQuery(
                "SELECT   products.*, product_images.*, product_specs.* ".
                "FROM     Products    AS products ".
                "JOIN     ProductImages AS product_images ".
                "ON       products.id = product_images.product_id ".
                "JOIN     ProductSpecs AS product_specs ".
                "ON       products.id = product_specs.product_id");
    

    which will only do a single query and give you the same information you wanted before.

    This is just one of those times where you have to identify expensive queries and choose an alternate method.