使用适当的主键和索引缓慢查询相对较小的表的MySQL

时间:2015-11-12 20:16:07

标签: mysql performance join

我在3个表上有一个select语句; T1和T2可以连接,T2和T3可以连接。 T3是一个只有42行的表。 T2真的很大,大约有40亿行,T1是750,000条记录。我想要的是,对于T1中的所有记录,我想从T3获得相关数据

如果我对所有3个表进行连接,如下所示,则查询需要很长时间才能运行:

select T1.A, T2.B, T3.C, T3.D from 
T1, T2, T3 where T1.A = T2.A 
and T1.B = T2.B and T2.C = T3.C

但是如果我从查询中取出T3,则查询运行得更快。我还使用EXPLAIN来查找查询路径。看起来对于T3来说,它正在进行全表扫描。即,键列为NULL。

所以,我的问题是为什么会这样做?

T3有一个主键,它是一个相对较小的表。我的整体查询是否因为T1和T2加入后缓慢,对于所有剩余的记录,它是否使用T3进行全表扫描?因此,如果在T1和T2之后有700,000条记录加入,那么对于这700,000条记录中的每条记录,它都会完全扫描T3表。那么,它就像做700,000 x 42扫描一样?

更新

为了更简单的理解,我用T1,T2,T3替换了我的原始表名。但这是我的实际问题:

select vc.vkey, vc.enst, vi.`effect_code`, te.effect, te.impact
from Variants vc, var_RVS.variant_impact vi, var_RVS.`types_effects` te
where vi.effect_code = te.eid
and vc.vkey = vi.vkey 

以下是解释声明的输出:

+----+-------------+-------+------+-------------------------------------+-------------+---------+---------------------------------+------+-------------+
| id | select_type | table | type | possible_keys                       | key         | key_len | ref                             | rows | Extra       |
+----+-------------+-------+------+-------------------------------------+-------------+---------+---------------------------------+------+-------------+
|  1 | SIMPLE      | te    | ALL  | PRIMARY                             | NULL        | NULL    | NULL                            |   42 | NULL        |
|  1 | SIMPLE      | vi    | ref  | canonical_enst,vkey_idx,effect_code | effect_code | 4       | var_RVS.te.eid                  |  981 | Using where |
|  1 | SIMPLE      | vc    | ref  | allVsAllXref,vkey_enst              | vkey_enst   | 788     | var_RVS.vi.vkey,var_RVS.vi.enst |    1 | Using where |
+----+-------------+-------+------+-------------------------------------+-------------+---------+---------------------------------+------+-------------+

2 个答案:

答案 0 :(得分:2)

除非T3.C上有索引,否则必须扫描所有T3以查找满足if的记录。这与钥匙无关;鉴于您当前的架构(据我所知),没有其他方法可以找到满足此要求的记录。

答案 1 :(得分:0)

最坏的情况是,输出为750K * 4B * 42 = 126千万亿行。

EXPLAIN估计42 * 981 * 1 = 4万行。

如果有vi.effect_code = te.eid没有匹配行的情况,则可以使用较小的数字。

你没有过滤任何行。你期待什么?

EXPLAIN表明每个阶段都存在合适的索引,因此查询速度尽可能快。

“慢”的速度有多慢? 你得到多少行?