Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

JimNayzium's avatar

Query Builder vs. Stored Procedure for something fairly complex?

I am finding whenever the procedure of updating my database is pretty complex, and requires multiple tables, that doing it all in Laravel or in PHP takes 10-100 times longer to execute than just coming up with the very complicated storedProcedure to keep on the mysql side and run whenever I need it.

Is this a "no-duh" type thing to experienced developers? That doing the full query on the mysql side will always win in terms of speed in execution?

The reason I ask it this way is because my gut tells me that Laravel has all these amazing built in things that make coding the solution fairly easy at times, but then when I take the time to write a stored procedure it has typically blown the laravel execution time away by a large factor.

Assuming what we need at the end of the procedure can actually be provided by either a stored procedure manipulating the data results, and can also be achieve by manipulating the results inside laravel after a series of logic and ->gets and what not. (Meaning the end result is purely "apples-to-apples" and we end up with the exact same structured associative data array/record set in both cases.

Is it always going to be "faster" to stay in mysql for the query as long in the data manipulation process as possible, and what we are trying to weigh is "how much faster" type thing? I am just so new to it all I find myself doing all the function building in Query Builder and then not being happy with the speed of the results and then just redoing it all as a simple:

DB::select("CALL myStoredProcedure());

Here is the latest migration of the most recent stored procedure I wrote. This sp excecutes in an average of around 30-90 milliseconds, and the series of Laravel queries necessary to make it return the exact same dataset was taking 10-12 full seconds consistently.

Here is what I am doing exactly.

I have 3 tables that each pull data independently from 3 different API external sources. I store the results in JSON type columns raw and simple. I do not parse the incoming json into table columns.

A 4th table is a combination of all three of these tables and it does have independent columns to represent some of the property values of the fetched JSON data from the other three tables.

Worth noting: I am stuck in mysql 5.7 and MariaDB 10.4 which is why I am not using more robust JSON functions in the MYSQL.

Is it fair to assume for something with this many moving parts that will require multiple Models, Multiple queries, multiple ->each loops and ->filter and ->map and ->keyBy and ->toArray() that it will just always be a ton faster to take the time to create the storedProcedure?

OR is it more accurate to say that my particular USE CASE just happens to be that way?

0 likes
11 replies
LaryAI's avatar
Level 58

In your scenario, using a stored procedure is indeed a valid and often more efficient approach for several reasons:

  1. Proximity to Data: Stored procedures execute directly on the database server, which reduces the overhead of data transfer between the application and the database. This is particularly beneficial when dealing with large datasets or complex operations involving multiple tables.

  2. Optimization: Database engines like MySQL are optimized for set-based operations and can execute complex queries more efficiently than application-level code. Stored procedures can leverage these optimizations, especially when dealing with joins, aggregations, and other complex SQL operations.

  3. Reduced Network Latency: By executing the logic on the database server, you minimize the number of round trips between your application and the database, which can significantly reduce latency.

  4. Atomicity and Consistency: Stored procedures can encapsulate complex logic in a single transaction, ensuring that all operations are completed successfully or rolled back in case of an error, maintaining data integrity.

  5. Maintainability: While stored procedures can be complex, they centralize the logic in one place, which can be easier to maintain and optimize over time compared to scattered application-level code.

In your specific use case, where you are dealing with multiple tables and JSON data, the stored procedure approach is likely to be more efficient. The complexity of parsing JSON, performing multiple joins, and handling conditional logic is better suited for execution within the database.

However, there are some considerations:

  • Portability: Stored procedures are database-specific, which can make it harder to switch databases or use database-agnostic tools.
  • Development Complexity: Writing and debugging stored procedures can be more challenging than using a higher-level language like PHP.

In conclusion, for complex operations involving multiple tables and large datasets, stored procedures are often the better choice for performance. However, it's essential to weigh the benefits against the potential downsides, such as reduced portability and increased complexity in development.

Tray2's avatar

Not sure what you are trying to do, but it seems like you are storing json in your database, and that is a big no no in my book.

However, doing multiple insert from Laravel versus doing it with a procedure in the database, well the procedure will likely win every time. The main reason for that is that is only connects to the database once.

I work a lot with stored procedures at my day job, and they are really powerful, but like the AI response says, it makes it harder to move between different RDBMSs.

I would recommend moving the logic out into the php side, and use proper tables to store my data.

JimNayzium's avatar

@Tray2 The fundamental purpose of the application is to fetch dozens of end points worth of JSON, parse through it all and combine it to form a game that updates in one minute increments when sporting events are live.

So it just got to the point where I needed it all locally stored before I could reliably do the crunching of it all necessary to make the application work. So step one in my process is "Fetch a crap-ton of end points and store the RAW json data on my local server... (every 60 seconds in a JOB running in a queue worker")

Then the step-2 got very manageable which was "Manipulate all that dense JSON data into tiny chunks I could deliver to the game for consumption.." But until the dozens of end points of data was on my server, doing it all in a real time fetch and process and store into columns just was super unreliable for "timing out" on the server no matter how long I gave it... Just wasn't working well.

Maybe there is a better way to do it, but I initially set every end point up with its own incoming laravel Model class and table that matched every property of that incoming JSON data structure and was so proud of myself for doing it so perfectly by the book from tutorials on this website! Then, when it came time to crunch it all together Laravel just took forever to do things for me like:

->get()->keyBy('some_necessary_index')->toArray(); would just take like 30 seconds sometimes on 3000 rows of data, and the JSON creation like the stored procedure takes 40 milliseconds to execute...

AND TO BE CLEAR, I do indeed have "proper tables" storing the data. I just build those tables from queries that retrieve the raw fetched JSON structured data from my own database AFTER it has stored it from the initial fetches... Because when i did it all at once, it was too unreliable.

Tray2's avatar

@JimNayzium That is good, storing the json in a temp table then processing it into the proper tables is a good way to handle this. However traversing large sets of json data takes time.

And of course doing it with a stored procedure is always going to be faster than doing it with the query builder.

If you can't fetch the json in smaller chunks, then stick with the stored procedure.

I would however recommend updating your RDBMS to a later version, the json parsing has improved quite a bit.

JimNayzium's avatar

@Tray2 Thanks for the well thought out responses. I appreciate when someone answers with a teaching spirit! I am an old-dog and try to stick with best practices but am such a novice hobbiest it's hard to figure things out sometimes!

I am going through the Docker and Valet tutorials now on how to best set up my local environment FOR the exact reason of the 5.7 JSON limitations! I am such an old dog, I've not learned any local setup other than MAMP which has me stuck in Mysql 5.7!

What would you recommend for the easiest way to get my Mac Setup running Laravel locally with a javascript front end? I want to learn React Native also, so I assumed I would need to know Docker decently but Laravel Valet looks so much easier. I've stuck with my setup cuz it worked, but you are correct at the JSON stuff. Every time I do my tutorials to figure out my queries I have to convert all the new JSON methods to the older GROUP_CONCAT stuff and it's maddening.

unohuim's avatar

@JimNayzium I use Valet on my Mac, and did so by following step-by-step the Laravel installation docs.. but I think now it's Herd and I wouldn't be surprised if it were as easy to set up as valet was. I really do like being able to hit the browser with project.test and it just works.

1 like
JimNayzium's avatar

@Tray2 AWESOME information.

I am sure PHP Storm is better for Laravel, but will Herd/Valet offer as much goodness if I am in VS Code?

Tray2's avatar

@JimNayzium Yes, Herd is for serving the sites, PHPStorm/VSCode is for editing your code. Which editor you use doesn't really matter, use what you know. I do however recommend PHPStorm and the Laravel Idea plugin.

jdc1898's avatar

It sounds like a typical ETL process. To @tray2 point and your assumption, the DB will always win as it is doing, well, what it’s designed to do.

Assuming your comfortable migrating the SPs, if the DB changes, I se no foul. At the end of the day you can keep it how you have it until you find a reason to change it. I suspect you have more work to do so refactoring a SP into query builder could be a distraction and the juice simply isn’t worth the squeeze.

1 like
JimNayzium's avatar

@jdc1898 THIS is the exact information I was looking for worded how I needed it worded!

Meaning, in my head, I realized the SP has all sorts of reasons why it could be a headache later, but it also has what I thought were fundamentally sound reasons to "sometimes be the better solution."

And it's also encouraging to hear I am not an idiot for being able to make the database do things faster than Laravel can do them etc. I kept feeling like I was doing something wrong in laravel since the query builder results would take such a drastically longer time to execute!

Please or to participate in this conversation.