繁体   English   中英

如何用union联接表? MySQL的

[英]How to join tables with union ? mysql

我有两个表:

  1. 历史
  2. 商业

我想运行此查询:

SELECT name, talias.*
FROM
    (SELECT business.bussName as name history.*
        FROM history 
        INNER JOIN business on history.bussID = business.bussID
        WHERE history.activity = 'Insert' OR history.activity = 'Update' 
    UNION 
        SELECT name as Null, history.*
        FROM history 
        WHERE history.activity = 'Delete'

    ) as talias  
WHERE 1 
order by talias.date DESC
LIMIT $fetch,20

这个查询需要13秒钟,我认为问题在于Mysql联接了历史和业务表中的所有行! 虽然它应该只加入20行!

我该如何解决?

尝试这个:

SELECT h.*
FROM history AS h
WHERE (h.activity IN ('Insert', 'Update')
        AND EXISTS (SELECT * FROM business AS b WHERE b.bussID = h.bussID))
    OR h.activity = 'Delete'
ORDER BY h.date DESC
LIMIT $fetch, 20

为了使ORDER BYLIMIT有效,请确保您在history.date上有一个索引。

如果我理解正确,那么您希望deleted历史记录中所有deleted活动的行,以及所有那些活动为“插入”或“更新” 并且在业务表中有对应行的行。

我不知道这是否会比您的查询更快-您将需要检查执行计划以验证这一点。

SELECT  *
FROM history 
where activity = 'Delete'
   or (     activity in ('Insert','Update')
        AND exists (select 1 
                    from business 
                    where history.bussID = business.bussID))
order by `date` DESC
LIMIT $fetch,20

编辑 (问题更改后)

如果确实需要业务表中的列,则用外部联接替换union 可以提高性能。

但是说实话,我没想到。 MySQL优化器不是很聪明,如果外部联接实际上是使用某种联合实现的,我也不会感到惊讶。 同样,只有您可以通过查看执行计划来进行测试。

SELECT h.*,
       b.bussName as name
FROM history 
  LEFT JOIN business b 
         ON h.bussID = b.bussID
        AND h.activity in ('Insert','Update')
WHERE h.activity in ('Delete', 'Insert','Update')
ORDER BY h.`date` DESC
LIMIT $fetch,20

顺便说一句: date是一个可怕的列名称。 首先是因为它是保留字,其次(也是更重要的原因)是因为它没有记录任何内容。 那是“创建日期”吗? “删除日期”? “到期日”? 还有其他日期吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM