【问题标题】:MySQL Join Query is very SlowMySQL Join 查询很慢
【发布时间】:2014-03-15 10:57:47
【问题描述】:

我正在执行一个 MySQL 连接查询,但它永远不会完成:

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`

person 表和 temp_table 具有完全相同的列。

当我使用 explain 运行查询时,我看到以下结果:

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

我使用以下语句为两个表创建了索引:

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

每个表都有相同的 100,000 行左右,因此连接应该返回 100,000 行。我假设这个查询很慢,因为在 t1 表上扫描的行数。如果我应用了索引,我不确定为什么会这样。任何帮助,将不胜感激。

【问题讨论】:

    标签: mysql sql join indexing


    【解决方案1】:

    具有相同的列并不能保证 1-1 匹配,除非列的组合是唯一的。

    尝试运行此查询:

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

    这将给出每个组合的计数。如果你只得到一行,在cnt 列中有一个“1”,那么你的查询应该没问题。如果你得到其他值,那么你实际上是在乘以行数,这会导致你的性能问题。

    编辑:

    您的输出似乎是:

    2564    37
    2565    1
    2566    1
    

    这意味着三列的 37 种组合出现了 2,564 次。正是这些在结果集中产生了 2,564*2,564*37 行(243,241,552 行)。这是很多行,可能解释了为什么您的查询很慢。

    【讨论】:

    • 我运行查询并得到以下输出:2564 37 2565 1 2566 1
    • 你想做什么?
    • 我真的只想要两个表中匹配的记录(通过日期、名称、国家 ID 的组合)。
    【解决方案2】:

    连接将元组的数量相乘。尝试使用自然加入或 group by。

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

    我不知道mysql,但这应该可以在psql中工作,应该是类似的。

    【讨论】:

    • 我尝试了自然连接,它只是坐着运行。不确定到底发生了什么。这看起来很简单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-04
    • 1970-01-01
    • 2012-06-26
    相关资源
    最近更新 更多