"加入"两个表之间非常快,而#34;左连接"这是非常慢的(MySQL DB)

时间:2016-01-26 17:45:01

标签: mysql sql performance

我有两个表(每个表约300,000行),其中一个列标识符列(ID)已编制索引。以下查询需要几秒钟:

SELECT *
FROM Table_1 a JOIN Table_2 b on a.ID=b.ID

以下查询需要数小时:

SELECT *
FROM Table_1 a LEFT JOIN Table_2 b on a.ID=b.ID

两个查询之间的区别在于,一个是使用" join"和一个"左连接"。

查询结果需要包含Table_1中的所有行,所以我别无选择,只能执行"左连接"。

同样尝试了这种方法也花费了大量时间:

SELECT *
FROM Table_1 a JOIN Table_2 b on a.ID=b.ID

UNION

SELECT *
FROM Table_1 a LEFT JOIN Table_2 b on a.ID=b.ID
WHERE b.ID is null;

有什么建议吗?

提前感谢分配...

4 个答案:

答案 0 :(得分:1)

根据所提供的信息,我只能想到尝试这样的事情:

SELECT a.*, b.column1, b.column2, ...
FROM Table_1 a JOIN Table_2 b on a.ID=b.ID

UNION

SELECT a.*, '' AS column1, '' AS column2, ...
FROM Table_1 a 
WHERE a.ID NOT IN 
     (SELECT a.ID FROM Table_1 a JOIN Table_2 b on a.ID=b.ID);

答案 1 :(得分:0)

JOIN等同于INNER JOIN,因此第一个查询将返回ID 匹配的。这里的索引也有助于提高性能。

你的第二个查询执行LEFT JOIN,正如你指出的那样返回表A中的所有内容,无论它是否与表B中的内容匹配。

答案 2 :(得分:0)

您的问题是您需要300,000条可能未编制索引的数据记录。实际上只有两件事可以帮助加快速度。第一,在id列的表上放置一个索引。第二,只选择你需要的列,而不是选择一切。例如:

bool callingThisFunction(const char * ptr1, const char * ptr2, const char * ptr3)
{
    return true;
}

int main(int argc, char ** argv)
{
    if (argc == 4)
    {
        char * executeablename = argv[0];
        char * p1 = argv[1];
        char * p2 = argv[2];
        char * p3 = argv[3];
        bool result = callingThisFunction(p1, p2, p3);
    }
    return 0;
}

这将减少正在处理的数据量。

答案 3 :(得分:0)

对于此查询:

SELECT *
FROM Table_1 a LEFT JOIN
     Table_2 b
     on a.ID = b.ID;

您需要table_2(id)上的索引。如果您在Table_2上没有以id开头的索引,我预计会有非常差的表现。

内部联接可以利用任一表上的索引。对于left join,第二个表上的索引更重要。