左加入两个视图很慢?

时间:2014-03-04 19:07:00

标签: mysql join

SELECT DISTINCT
viewA.TRID, 
viewA.hits,
viewA.department,
viewA.admin,
viewA.publisher,
viewA.employee,
viewA.logincount,
viewA.registrationdate,
viewA.firstlogin,
viewA.lastlogin,
viewA.`month`,
viewA.`year`,
viewA.businesscategory,
viewA.mail,
viewA.givenname,
viewA.sn,
viewA.departmentnumber,
viewA.sa_title,
viewA.title,
viewA.supemail,
viewA.regionname
FROM
viewA
LEFT JOIN viewB ON viewA.TRID = viewB.TRID
WHERE viewB.TRID IS NULL 

我有两个视图,其中包含大约10K和5K的记录。他们每个人都很快进入 - 几分之一秒。当我尝试从ViewA获取ViewB中没有的所有记录时,它可以工作,但速度非常慢。所有底层TRID字段都是相同的字符集,并且全部设置为varchar(10),索引和表都是Innodb。现在查询需要16秒。我能做什么?

2 个答案:

答案 0 :(得分:4)

通常,使用JOIN,MySQL必须为每个连接记录执行查找。使用密钥时查找速度很快,但在您的情况下,实际上没有任何密钥,因为连接表是一个视图。

要尝试让MySQL在第一个视图中的每个记录中运行第二个视图后面的查询,我们可以使用子查询。

SELECT *
FROM viewA
WHERE TRID NOT IN (SELECT TRID FROM viewB);

这应该允许MySQL在子查询中获取viewB的所有TRID值(在临时表中),然后在viewA中为每个记录搜索它们。

来自MySQL docs

  

MySQL只执行一次不相关的子查询。使用EXPLAIN来制作   确定给定的子查询确实是不相关的。

答案 1 :(得分:0)

在MySQL中使用视图优化查询很困难。我的第一个建议就是摆脱distinct除非你绝对知道它是必要的。

然后您可以将性能与此查询进行比较:

select viewA.*
from viewA
where not exists (select 1 from viewB where viewB.TRID = viewA.TRID);

很难说一个人会比另一个更好,但是值得尝试看看这个是否更好。