为什么这个简单的左连接需要永远执行?

Kel*_*sen 3 mysql query-optimization left-join

我正在对一个旧的mysql数据库运行查询,并且许多查询花费的时间比他们应该的要长得多.例如,ad_vehicle有60000行,id_ad_link有25000行

SELECT * FROM autotalk_identicar_old.ad_vehicle 
left join autotalk_identicar_old.id_ad_link on autotalk_identicar_old.ad_vehicle.vehiclekey=autotalk_identicar_old.id_ad_link.rbvehiclekey;
Run Code Online (Sandbox Code Playgroud)

持续时间是2.323秒,在执行命令后12分钟仍然需要获取(使用mysql工作台,但不确定这是否有所不同).运行在带有3核myd四核@ 3.4ghz和1GB内存的虚拟机中运行

我不认为有任何索引/主键会产生如此大的差异吗?

前几行ad_vehicle

A145 00AA, PV, ALFA, 145, 2000, 3HBm, 1.6, , , , , P, , 5, 1596, , , 32995,  , , 3HBm 1.6p
A145 00AB, PV, ALFA, 145, 2000, 3HBm, 1.7, , , , , P, , 5, 1712, , , 41995,  , , 3HBm 1.7p
A145 01AA, PV, ALFA, 145, 2001, 3HBm, 1.6, , , , , P, , 5, 1596, , , 32995,  , , 3HBm 1.6p
A145 01AB, PV, ALFA, 145, 2001, 3HBm, 1.7, , , , , P, , 5, 1712, , , 41995,  , , 3HBm 1.7p
A145 02AA, PV, ALFA, 145, 2002, 3HBm, 1.6, , , , , P, , 5, 1596, , , 32995,  , , 3HBm 1.6p
A145 02AB, PV, ALFA, 145, 2002, 3HBm, 1.7, , , , , P, , 5, 1712, , , 41995,  , , 3HBm 1.7p
A145 95AA, PV, ALFA, 145, 1995, 3HBm, 1.6, , L, , , P, , 4, 1596, , , 32995,  , , 3HBm 1.6p L
A145 95AB, PV, ALFA, 145, 1995, 3HBm, 1.7, ELEGANTE, L, , , P, , 4, 1712, , , 41995,  , , 3HBm 1.7p ELEGANTE L
A145 96AA, PV, ALFA, 145, 1996, 3HBm, 1.6, , L, , , P, , 4, 1596, , , 32995,  , , 3HBm 1.6p L
A145 96AB, PV, ALFA, 145, 1996, 3HBm, 1.7, ELEGANTE, L, , , P, , 4, 1712, , , 41995,  , , 3HBm 1.7p ELEGANTE L
A145 97AA, PV, ALFA, 145, 1997, 3HBm, 1.6, , L, , , P, , 4, 1596, , , 32995,  , , 3HBm 1.6p L
A145 97AB, PV, ALFA, 145, 1997, 3HBm, 1.7, ELEGANTE, L, , , P, , 4, 1712, , , 41995,  , , 3HBm 1.7p ELEGANTE L
A145 98AA, PV, ALFA, 145, 1998, 3HBm, 1.6, , L, , , P, , 4, 1596, , , 32995,  , , 3HBm 1.6p L
A145 98AB, PV, ALFA, 145, 1998, 3HBm, 1.7, ELEGANTE, L, , , P, , 4, 1712, , , 41995,  , , 3HBm 1.7p ELEGANTE L
A145 98AC, PV, ALFA, 145, 1998, 4SDm, 2.5, , , , , P, , 5, 2492, , , 65998,  , , 4SDm 2.5p
A145 99AA, PV, ALFA, 145, 1999, 3HBm, 1.7, ELEGANTE, L, , , P, , 4, 1712, , , 41995,  , , 3HBm 1.7p ELEGANTE L
A145 99AB, PV, ALFA, 145, 1999, 3HBm, 1.6, , L, , , P, , 4, 1596, , , 32995,  , , 3HBm 1.6p L
A146 00AA, PV, ALFA, 146, 2000, 5HBm, 1.6, , TS, , , P, , 5, 1596, , , 37995,  , , 5HBm 1.6p TS
A146 01AA, PV, ALFA, 146, 2001, 5HBm, 1.6, , TS, , , P, , 5, 1596, , , 38995,  , , 5HBm 1.6p TS
Run Code Online (Sandbox Code Playgroud)

前几行id_ad_link

4   10  DHJT 94AA   1994    REDUNDANT   HIJET
12  971 A33  95AA   1995    REDUNDANT   ALFA33
13  971 A33  95AB   1995    REDUNDANT   ALFA33
14  971 A33  95AC   1995    REDUNDANT   ALFA33
61  973 A146 95AB   1995    REDUNDANT   146
60  973 A146 95AA   1995    REDUNDANT   146
59  973 A145 02AB   2002    REDUNDANT   145
58  973 A145 02AA   2002    REDUNDANT   145
57  973 A145 01AB   2001    REDUNDANT   145
56  973 A145 01AA   2001    REDUNDANT   145
55  973 A145 00AB   2000    REDUNDANT   145
54  973 A145 99AB   1999    REDUNDANT   145
53  973 A145 99AA   1999    REDUNDANT   145
52  973 A145 98AC   1998    REDUNDANT   145
45  973 A145 95AB   1995    REDUNDANT   145
44  973 A145 95AA   1995    REDUNDANT   145
70  973 A146 98AB   1998    REDUNDANT   146
71  973 A146 98AC   1998    REDUNDANT   146
72  973 A146 99AA   1999    REDUNDANT   146
73  973 A146 00AA   2000    REDUNDANT   146
Run Code Online (Sandbox Code Playgroud)

更新:

这是结果

explain SELECT * FROM autotalk_identicar_old.ad_vehicle 
left join autotalk_identicar_old.id_ad_link on autotalk_identicar_old.ad_vehicle.vehiclekey=autotalk_identicar_old.id_ad_link.rbvehiclekey;

id, select_type, table,       type,    possible_keys, key,  key_len, ref, rows,   Extra
'1', 'SIMPLE', 'ad_vehicle', 'ALL',        NULL,     NULL,   NULL,  NULL, '60433', ''
'1', 'SIMPLE', 'id_ad_link', 'ALL',        NULL,     NULL,   NULL,  NULL, '25571', ''
Run Code Online (Sandbox Code Playgroud)

Boh*_*ian 7

尝试在外键上创建索引:

create index id_ad_link_rbvehiclekey_index on id_ad_link(rbvehiclekey);
Run Code Online (Sandbox Code Playgroud)

如果没有此索引,则每一行都ad_vehicle将导致完整的表扫描id_ad_link.
使用索引,每行将ad_vehicle导致访问一些索引页(可能在内存中),并且读取少量页以获取连接的行,因为索引存储页面以查找行.

最小化磁盘I/O对性能至关重要,因为它至少比内存操作慢1000倍.

索引产生巨大差异,尤其是用于连接的列(如外键)