我在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 |
+----+-------------+-------+------+-------------------------------------+-------------+---------+---------------------------------+------+-------------+
答案 0 :(得分:2)
除非T3.C上有索引,否则必须扫描所有T3以查找满足if
的记录。这与钥匙无关;鉴于您当前的架构(据我所知),没有其他方法可以找到满足此要求的记录。
答案 1 :(得分:0)
最坏的情况是,输出为750K * 4B * 42 = 126千万亿行。
EXPLAIN
估计42 * 981 * 1 = 4万行。
如果有vi.effect_code = te.eid
没有匹配行的情况,则可以使用较小的数字。
你没有过滤任何行。你期待什么?
EXPLAIN
表明每个阶段都存在合适的索引,因此查询速度尽可能快。
“慢”的速度有多慢? 你得到多少行?