Mysql 使用ORDER BY';x';使用联接,但保留不带';t没有'的值;x';
这是一个相对复杂的问题的简化版本,我和我的同事无法完全理解这个问题 考虑两个表,Mysql 使用ORDER BY';x';使用联接,但保留不带';t没有'的值;x';,mysql,optimization,Mysql,Optimization,这是一个相对复杂的问题的简化版本,我和我的同事无法完全理解这个问题 考虑两个表,表a和表b。在我们的CMS中,table_a保存数据库中存储的所有数据的元数据,table_b有一些更具体的信息,因此为了简单起见,一个title和date列 目前,我们的查询如下所示: SELECT * FROM `table_a` LEFT OUTER JOIN `table_b` ON (table_a.id = table_b.id) WHERE table_a.col = 'value' ORDER BY
表a
和表b
。在我们的CMS中,table_a
保存数据库中存储的所有数据的元数据,table_b
有一些更具体的信息,因此为了简单起见,一个title
和date
列
目前,我们的查询如下所示:
SELECT *
FROM `table_a` LEFT OUTER JOIN `table_b` ON (table_a.id = table_b.id)
WHERE table_a.col = 'value'
ORDER BY table_b.date ASC
LIMIT 0,20
当表a
有大量行时,这种情况会严重恶化。如果更改了联接右外部联接
(这会触发MySQL使用table_b.date
上设置的索引),则查询速度会无限快,但不会产生相同的结果(因为如果table_b.date
没有值,则会忽略它)
这在我们的CMS中成为一个问题,因为如果用户在日期列上排序,任何没有设置日期的行都会从界面中消失,从而造成混乱的用户界面体验,并且很难为缺少日期的行添加日期
是否有一种解决方案可以:
表b
。日期索引,以便
该查询将更好地扩展表b
设置以便用户可以输入
资料我要谈谈second ArtoAle的评论。由于
order by
应用于表b
中缺少行的外部联接中的空值,因此这些行无论如何都会出现顺序错误
模拟的外部连接是丑陋的部分,所以让我们先看看它。Mysql除了之外没有,因此您需要根据存在编写查询
SELECT table_a.col1, table_a.col2, table_a.col3, ... NULL as table_b_col1, NULL as ...
FROM
table_a
WHERE
NOT EXISTS (SELECT 1 FROM table_a INNER JOIN table_b ON table_a.id = table_b.id);
它应该是UNION ALL
ed,并将原始查询作为内部联接。需要使用UNION\u ALL
来保持原始顺序
无论您做什么,这种查询可能都会非常慢,因为不会有一个索引随时支持“外键不存在”类型的查询。这基本上可以归结为表_a.id中的索引扫描以及表_b.id中对应行的查找(或者并行扫描) 我要谈谈第二艺术节的评论。由于
order by
应用于表b
中缺少行的外部联接中的空值,因此这些行无论如何都会出现顺序错误
模拟的外部连接是丑陋的部分,所以让我们先看看它。Mysql除了之外没有,因此您需要根据存在编写查询
SELECT table_a.col1, table_a.col2, table_a.col3, ... NULL as table_b_col1, NULL as ...
FROM
table_a
WHERE
NOT EXISTS (SELECT 1 FROM table_a INNER JOIN table_b ON table_a.id = table_b.id);
它应该是UNION ALL
ed,并将原始查询作为内部联接。需要使用UNION\u ALL
来保持原始顺序
无论您做什么,这种查询可能都会非常慢,因为不会有一个索引随时支持“外键不存在”类型的查询。这基本上可以归结为表_a.id中的索引扫描以及表_b.id中对应行的查找(或者并行扫描) 因此,我们最终实现了一个不同的解决方案,虽然结果不如使用索引,但它仍然提供了大约25%的速度提升 我们删除联接,而是使用ORDER BY子查询:
SELECT *
FROM `table_a`
WHERE table_a.col = 'value'
ORDER BY (
SELECT date
FROM table_b
WHERE id = table_a.id
) ASC
LIMIT 0,20
因此,我们最终实现了一个不同的解决方案,虽然结果不如使用索引,但它仍然提供了大约25%的速度提升 我们删除联接,而是使用ORDER BY子查询:
SELECT *
FROM `table_a`
WHERE table_a.col = 'value'
ORDER BY (
SELECT date
FROM table_b
WHERE id = table_a.id
) ASC
LIMIT 0,20
你可以做一个正确的连接加上一个联合…你可以做一个正确的连接加上一个联合。。。