Your solution will lead to redundancy of course, but if you prefer the speed over that, it's okay to go with that solution.
For your current situation, make sure that you are indexing the columns that you are using.
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
For simplicity, I'm gonna use different table names than my current project.
I have tables t1, t2 with many to many relationships and pivot table t1_t2 which have t1_id and t2_id columns, and at the beginning, I start using doesntHave query like this.
T1::doesntHave('t2')->get();
After a while, the tables become bigger and bigger with millions of records and the query took more than a minute, then I used joins instead to get the same results with better performance, like this.
T1::select(['t1.id','t1.column_name'])
->leftJoin('t1_t2', 't1.id', '=', 't1_t2.t1_id')
->whereNull('t1_t2.t1_id')
->limit(10)
->get();
Now, t1 has 5M records and t2 has 100K and t1_t2 has 11M and the join query takes from 7 to 10 seconds and we expect more records.
Are there any other ways I can do to get records from t1 which doesn't have a relationship with t2 with better performance?
I think I missing something cause for sure MySQL performance is better than that.
The only thing I get in my mind, for now, is making a new column "has_relashion_with_t2" with boolean values and default value 0 in t1 table and automatically converting the value to 1 when attaching t1 to t2 to avoid join query, but I don't like this method which will lead to redundancy in data and increase bugs.
Any help?
Please or to participate in this conversation.