简体   繁体   中英

MySQL Join Query is very Slow

I have a MySQL join query that I am executing and it never finishes:

SELECT t1.`id` FROM `person` as t1 
      JOIN `temp_table` as t2 
      on t1.`date` = t2.`date` 
      and t1.`name` = t2.`name` 
      and t1.`country_id`= t2.`country_id`

The person table and temp_table have the exact same columns.

When I run the query with explain I see the following results:

1   SIMPLE  t1  index   test    test    777 NULL    99560   Using where; Using index
1   SIMPLE  t2  ref test    test    777 development.t1.date,development.t1.name,development.t1.country_id   1   Using index

I created indexes for both tables with the following statement:

ALTER TABLE `person` ADD INDEX `test` (`date`,`name`,`country_id`)
ALTER TABLE `temp_table` ADD INDEX `test` (`date`,`name`,`country_id`)

Each table has the same 100,000 rows or so in them, and thus the join should return 100,000 rows. I am assuming this query is so slow because of the number of rows being scanned on the t1 table. I'm not sure why that is the case though if I have applied indexes. Any help would be appreciated.

Having the same columns doesn't guarantee a 1-1 match, unless the combination of the columns is unique.

Try running this query:

select cnt, count(*)
from (select date,name, country_id, count(*) as cnt
      from person
      group by date,name, country_id
     ) t
group by cnt;

This will give a count of each combination. If you only get one row out of it, with a "1" in the cnt column, then your query should be ok. If you get other values, then you are actually multiplying the number of rows, which is causing your performance problem.

EDIT:

Your output appears to be:

2564    37
2565    1
2566    1

That means that 37 combinations of the three columns occur 2,564 times. Just these are producing 2,564*2,564*37 rows in the result set (243,241,552 rows). That's a lot of rows and probably explains why your query is slow.

The join is multiplying the number of tuples. Try using a natural join or a group by instead.

SELECT t1.`id` FROM `person` as t1 
 NATURAL JOIN `temp_table` as t2

I don't know mysql, but that should work in psql, which should be similar.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM