[Solved] MySQL multiple inner join between 2 tables on different columns for one of the tables
Looking to automatically optimize YOUR SQL query? Start for free.

EverSQL Database Performance Knowledge Base

MySQL multiple inner join between 2 tables on different columns for one of the tables

Database type:

Table transport

Id  | FirstLevSubcat | SecondLevSubcat | ThirdLevSubcat 
 8  |   4            |   27            |  1418

Table categories

Id    | CategoriesUrl
 4    |   cars          
 27   |   audi          
 1418 |   audi-100

Query if not to use categories table (without inner join) would be like

SELECT count(*) FROM transport
WHERE FirstLevSubcat = 4 AND SecondLevSubcat = 27 AND ThirdLevSubcat = 1418

Trying to get the same result using INNER JOIN

SELECT count(*) FROM transport main_table 
INNER JOIN categories cat_table_first ON cat_table_first.IdRows = main_table.FirstLevSubcat 
INNER JOIN categories cat_table_second ON cat_table_second.IdRows = main_table.SecondLevSubcat 
INNER JOIN categories cat_table_third ON cat_table_third.IdRows = main_table.ThirdLevSubcat 
cat_table_first.CategoriesUrl = 'cars' 
AND cat_table_second.CategoriesUrl = 'audi' 
AND cat_table_third.CategoriesUrl = 'audi-100' 

At first sight all works

But is such query ok? May be can improve something?

How to optimize this SQL query?

The following recommendations will help you in your SQL tuning process.
You'll find 3 sections below:

  1. Description of the steps you can take to speed up the query.
  2. The optimal indexes for this query, which you can copy and create in your database.
  3. An automatically re-written query you can copy and execute in your database.
The optimization process and recommendations:
  1. Create Optimal Indexes (modified query below): The recommended indexes are an integral part of this optimization effort and should be created before testing the execution duration of the optimized query.
Optimal indexes for this query:
ALTER TABLE `transport` ADD INDEX `transport_idx_firstlevsu_secondlevs_thirdlevsu` (`FirstLevSubcat`,`SecondLevSubcat`,`ThirdLevSubcat`);
The optimized query:
        transport.FirstLevSubcat = 4 
        AND transport.SecondLevSubcat = 27 
        AND transport.ThirdLevSubcat = 1418

Related Articles

* original question posted on StackOverflow here.