Eloquent Performance Tradeoffs0:00
They say that using Eloquent just automatically degrades the performance of our application, and that real applications need to use raw SQL statements. The truth of it is that, yes, Eloquent does have an overhead, especially compared to just raw queries. But you know, Eloquent is just a tool. It's an ORM, and you know, anything I say about Eloquent applies to any ORM. It does have an overhead, but the whole idea behind something like Eloquent is to make
It does have an overhead, but the whole idea behind something like Eloquent is to make it easier to not just work with the data that we need, but find the data that we need. Because I'm sure that some of us are database admins or SQL masters. I'm certainly not. I can do your basic query, your basic joins, left join, right join, all of that stuff. But when it starts getting into the nitty gritty of anything, something like an ORM is
But when it starts getting into the nitty gritty of anything, something like an ORM is going to make my life so much easier. And that's why Eloquent exists. So yes, there is an overhead, but that overhead is negligible. Really, the main problem that we need to be concerned with is to be sure that our use of Eloquent doesn't introduce any kind of performance issues because it's very possible. But Eloquent is just a tool.
Introducing N+1 Problem1:26
possible. But Eloquent is just a tool. And any good tool is going to already solve the problems that could arise by using that tool. Let me show you. Like first, we're going to look at what's called the n plus one problem. If you're not familiar with that, it's very simple. So first of all, I have some posts that I want to display. So we are going to fetch all of the posts.
So first of all, I have some posts that I want to display. So we are going to fetch all of the posts. And then we want to send those to the view. So we will just do that very easily and simply there. There's nothing out of the ordinary here. We're just fetching the posts. And then we are going to display them inside of the view. And if we look at the view, here we have a for loop. We are iterating over each post. We're displaying the post information.
We are iterating over each post. We're displaying the post information. And then here we have a placeholder to display the author name, which we will get to here in a moment. So if we take a look at this in the browser, of course, we see all of the posts there. I think there's 10 authors and 10 posts for each author, I think. So we are displaying all of those posts and, you know, we can take a look at the actual
So we are displaying all of those posts and, you know, we can take a look at the actual query that executed because I have telescope installed. So if we take a look here, you know, never mind about the sessions. We don't care about those. What we care about is this right here where we are selecting everything from our posts. That is our one query. And of course, we select those, we display those, but I want to display the author information
And of course, we select those, we display those, but I want to display the author information here as well. So right here where I have this placeholder, we are going to reach into our author relationship so that we can display the name. Now I'm doing this inside of this for each loop, which makes perfect sense because, you know, we want to display the name for that given post, or at least the author's name
know, we want to display the name for that given post, or at least the author's name of that given post. So let's say that, and instead of the browser, sure enough, we see not just the post information, but the name of the author. So for 100 posts, we have 10 authors and each author has 10 posts if we were to count those. But let's take a look at the queries. We see something drastically different here.
But let's take a look at the queries. We see something drastically different here. So once again, let's ignore the session stuff. But look at what we have select everything from authors where the author ID is 10. And we don't just do that once. We do that one, two, three, four, five, six, seven, eight, nine, and 10. And that's just for the author with 90 of 10. We also do the same thing for the author with an ID of nine and eight and seven all the
We also do the same thing for the author with an ID of nine and eight and seven all the way down to the first author. And the reason why is because, wow, yes, we have fetched all of our posts here. As we iterate over those posts, we want to display the author name and we don't have that information at that given time. So every time we iterate through this loop, we are going out and fetching the author information for the post that we are currently displaying.
author information for the post that we are currently displaying. So therefore, in this case, that's what 100 queries. That's the N plus one problem. N is the 100 queries in this case. And then the one is, well, our first query here. But of course, it's an N plus one. So that number is going to vary based upon, you know, the data that we want to display. But as I said, you know, every tool has its own solution for the problems that
Fixing with Eager Loading4:44
display. But as I said, you know, every tool has its own solution for the problems that it doesn't necessarily cause, but the problems that can arise by using that tool. So what we could do here is just eager load the author information because eloquent gives us the ability to include any relation information that we might need using the with method. So get the posts with the author information and then get those. Now we need to clear what we see inside of telescope here.
So get the posts with the author information and then get those. Now we need to clear what we see inside of telescope here. But if we hit the database now and we take a look at the queries, now we only see two, we select all of the posts and then we get the author information for the authors of those posts. Behind the scenes, eloquent is making two queries on our behalf to fetch all of the information that we need because we've already told it, hey, we want the post information,
the information that we need because we've already told it, hey, we want the post information, but we also are going to use the author information. So we've gone from, you know, in this case, 101 queries to just two, and we didn't have to do any of the extra processing or anything like that because eloquent did it for us. As I said, it's a tool and makes it easier to work with the data that we want to work
Counting Related Records5:57
As I said, it's a tool and makes it easier to work with the data that we want to work with and find the data that we want to find eager loading is that the only tool that eloquent provides. Let's say that you don't need the full author model. You just want a post count for an admin dashboard or something like that. So you could do something like this. We could get authors and then we would use our author model with count posts. So this is going to fetch, of course, the author information, but it's also
We could get authors and then we would use our author model with count posts. So this is going to fetch, of course, the author information, but it's also going to include the count of the posts with that author information. And I don't have any way to display this, but we could definitely see it inside of telescope. So let's clear our results here. Let's make our request so that now we can look at our queries. Of course, we see the same two queries that we saw before to where we were or we select
Of course, we see the same two queries that we saw before to where we were or we select all of the posts, we get all of the authors for those posts. But here's the query that we get to the count. So we are selecting everything from authors, but we are also selecting the count of posts where the author's ID is well in the authors that we are working with it, that truncated everything else, but that's the overall idea. So it's one query to do all of that.
everything else, but that's the overall idea. So it's one query to do all of that. It's an efficient sub query and we can access it as we iterate over our authors by using the posts count attribute. And that's it. Let's do this. Let's say that, you know, as we are displaying our posts here and we are including the author information, maybe as we display everything here, we also want to include the
including the author information, maybe as we display everything here, we also want to include the number of posts that that author made. So that's we could do something like this to where we'd have post author and then posts count or it wouldn't be post count. It would be posts count because that is the name of the relationship there. Well, we can do that because eloquent gives us the ability to make more advanced queries
Well, we can do that because eloquent gives us the ability to make more advanced queries very easily. Our query here though is going to change a little bit differently so that we are still going to get all of our posts and we still want to include the author information, but we also want to include the count of the posts. So we'll just call with count posts and there we will have our query. So once again, let's go to telescope.
So we'll just call with count posts and there we will have our query. So once again, let's go to telescope. Let's clear our results here, then let's take a look and it helps if we output the information correctly. All right. With that, let's clear our results from telescope again, we refresh and here is our results. So we select all of our posts, then we select the authors based upon the IDs from the posts
So we select all of our posts, then we select the authors based upon the IDs from the posts that we have, but we also include the count. So once again, we are still doing two queries here, but it's an efficient query with a sub query to get the count and then we see the result to where we have not just the post information and not just the author name, but also the number of posts that each author is made, which is going to be 10 for each one of those.
each author is made, which is going to be 10 for each one of those. And so yes, we could have written that raw SQL. We could have executed that raw SQL, but would it be as quick to do as this? And the overhead for executing this is negligible compared to running the raw SQL. So if the performance between eloquent and raw SQL is negligible, then you know , what else are they going to say? Well, next they're going to say that eloquent hides the things that are going
Inspecting Generated Queries9:49
else are they going to say? Well, next they're going to say that eloquent hides the things that are going on behind the scenes. And no, no ORM is going to hide what's going on behind the scenes. It's just not possible because the ORM has to know how to interact with the database. I mean, you know, yes, there are tools like telescope that we could use. But you know, some of these things are truncated and that's not really going to help us.
But you know, some of these things are truncated and that's not really going to help us. So what could we do? Well, we could do this in several different ways, but one of the easiest things that we could do is something like this to where we will use the DB facade. And there's a method called enable query log. So this is going to enable the query log so that after we execute our query here, which we need to go back, we need to call get.
here, which we need to go back, we need to call get. And then we can DD out the query log results, basically. So we will call get query log and that's going to display all of the queries that took place between when we enabled the log and we displayed the log. So let's be sure that we are outputting the author information. Let's go to the browser. Let's refresh here. Herd is going to pop back up.
Let's refresh here. Herd is going to pop back up. But now we can see that we have an array. And the reason why we have an array is because there were multiple queries that were executed. The first query is the first one, select all from posts. So we were able to see that query. If there were any bindings, we would see the bindings there. We could also see the amount of time that it took for that query to execute. But then there's another query.
We could also see the amount of time that it took for that query to execute. But then there's another query. We have the query to select not just all of the author information, but also the count of posts for each individual author so that we could display that. We can see that it is selected as posts underscore count. And then once again, the bindings, if we needed those, as well as the time for that query to execute. So nothing is hidden there.
query to execute. So nothing is hidden there. We can access that information. We can see it. If that is indeed what we want to do, which sometimes we do, sometimes we don't . But that ability is there. So yes, eloquent doesn't hide anything from us. So ultimately it comes down to knowing how to use eloquent. It isn't slow.
Eloquent Best Practices11:59
So ultimately it comes down to knowing how to use eloquent. It isn't slow. The ORM provides tools to write efficient queries. We can eager load data. Relationship aggregates are all available to us to make working with relationships easier. We can inspect the queries that execute and a ton of other things because, you know, as I've said, eloquent is a tool that it provides everything that we need to work with a database.
I've said, eloquent is a tool that it provides everything that we need to work with a database. The responsibility of using eloquent is up to us. So yes, we need to know how to use eloquent in order to write performant and efficient applications.
