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秒。我能做什么?
答案 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);
很难说一个人会比另一个更好,但是值得尝试看看这个是否更好。