我有两张桌子:
我想运行此查询:
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行!
我该怎么办呢?
答案 0 :(得分:0)
试试这个:
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 BY
和LIMIT
有效,请确保您在history.date
上有索引。
答案 1 :(得分:0)
如果我理解正确,您希望活动为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
是一个可怕的专栏名称。首先是因为它是一个保留字,第二个(更重要)因为它没有记录任何东西。那是"创作日期"? "删除日期"? A"截止日期"?还有其他日期吗?