Skip to main content
added 631 characters in body
Source Link

To understand the reason behind slowness of your current query, you need to understand the Nested Loop Join algorithm used by MySQL. Basically, for every country_code value in the country table, it is looking for all the matching rows in the statistic table. So if you look at your explain, it is roughly accessing 334*306 rows (a large number). Unfortunately, in this case, MySQL optimizer is not smart enough to stop searching for the row as soon as a match is found (because you are using Group By, and no aggregation function is being used).

Now, JOIN is unnecessary here, as it seems that you are just looking to check that the "country" has atleast one corresponding row in the statistic_detail table. This query can be written in a more performant way using EXISTS() on a Correlated Subquery.

Try the following query; it should be able to use the country_idxExists() indexstops as soon as a matching row is found in the statistic_detailstatistic table).

Try the following query:

SELECT cd.country_name
FROM country_detail AS cd 
WHERE EXISTS (SELECT 1 FROM statistic_detail AS sd 
              WHERE sd.country = cd.country_code)

If country_name values are not UNIQUE in the country_detail table, you can additionally utilize DISTINCT clause to get rid of duplicates:

SELECT DISTINCT cd.country_name
FROM country_detail AS cd 
WHERE EXISTS (SELECT 1 FROM statistic_detail AS sd 
              WHERE sd.country = cd.country_code)

JOIN is unnecessary here, as it seems that you are just looking to check that the "country" has atleast one corresponding row in the statistic_detail table. This query can be written in a more performant way using EXISTS() on a Correlated Subquery.

Try the following query; it should be able to use the country_idx index in the statistic_detail table):

SELECT cd.country_name
FROM country_detail AS cd 
WHERE EXISTS (SELECT 1 FROM statistic_detail AS sd 
              WHERE sd.country = cd.country_code)

If country_name values are not UNIQUE in the country_detail table, you can additionally utilize DISTINCT clause to get rid of duplicates:

SELECT DISTINCT cd.country_name
FROM country_detail AS cd 
WHERE EXISTS (SELECT 1 FROM statistic_detail AS sd 
              WHERE sd.country = cd.country_code)

To understand the reason behind slowness of your current query, you need to understand the Nested Loop Join algorithm used by MySQL. Basically, for every country_code value in the country table, it is looking for all the matching rows in the statistic table. So if you look at your explain, it is roughly accessing 334*306 rows (a large number). Unfortunately, in this case, MySQL optimizer is not smart enough to stop searching for the row as soon as a match is found (because you are using Group By, and no aggregation function is being used).

Now, JOIN is unnecessary here, as it seems that you are just looking to check that the "country" has atleast one corresponding row in the statistic_detail table. This query can be written in a more performant way using EXISTS() on a Correlated Subquery. Exists() stops as soon as a matching row is found in the statistic table.

Try the following query:

SELECT cd.country_name
FROM country_detail AS cd 
WHERE EXISTS (SELECT 1 FROM statistic_detail AS sd 
              WHERE sd.country = cd.country_code)

If country_name values are not UNIQUE in the country_detail table, you can additionally utilize DISTINCT clause to get rid of duplicates:

SELECT DISTINCT cd.country_name
FROM country_detail AS cd 
WHERE EXISTS (SELECT 1 FROM statistic_detail AS sd 
              WHERE sd.country = cd.country_code)
Source Link

JOIN is unnecessary here, as it seems that you are just looking to check that the "country" has atleast one corresponding row in the statistic_detail table. This query can be written in a more performant way using EXISTS() on a Correlated Subquery.

Try the following query; it should be able to use the country_idx index in the statistic_detail table):

SELECT cd.country_name
FROM country_detail AS cd 
WHERE EXISTS (SELECT 1 FROM statistic_detail AS sd 
              WHERE sd.country = cd.country_code)

If country_name values are not UNIQUE in the country_detail table, you can additionally utilize DISTINCT clause to get rid of duplicates:

SELECT DISTINCT cd.country_name
FROM country_detail AS cd 
WHERE EXISTS (SELECT 1 FROM statistic_detail AS sd 
              WHERE sd.country = cd.country_code)