Mysql查询optiomization(避免使用UNION ALL)

时间:2016-11-21 09:31:07

标签: mysql sql

以任何方式存在如何优化给定查询?我希望始终得到user表的所有结果,以及picture表中的结果+(如果相关存在)。可以不使用UNION ALL

让我们考虑以下示例

 +----+--------+
| id | name   |
+----+--------+
|  1 | Drosos |
|  2 | Jack   |
+----+--------+

+----+---------+--------------+
| id | user_id | picture_name |
+----+---------+--------------+
|  1 |       1 | avatar.jpg   |
|  2 |       1 | avatar2.jpg  |
+----+---------+--------------+

预期结果

+--------+--------------+
| name   | picture_name |
+--------+--------------+
| Drosos | avatar.jpg   |
| Drosos | avatar2.jpg  |
| Drosos | NULL         |
| Jack   | NULL         |
+--------+--------------+
4 rows in set (0.00 sec)

用户

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;

图片表

CREATE TABLE `picture` (
  `id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `picture_name` varchar(45) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

查询

SELECT u.name, p.picture_name FROM user u
INNER JOIN picture p ON p.user_id = u.id
UNION ALL
SELECT u.name, NULL FROM user u;

http://sqlfiddle.com/#!9/46d18a/1

2 个答案:

答案 0 :(得分:1)

这是一种获取你所追求的方法,但实际上只是为了说明UNION ALL可能是你最好的解决方案。这是SQL Server语法,应该非常接近MySQL

SELECT u.name, p.picture_name 
FROM user u
CROSS JOIN
(SELECT 1 as C1 UNION ALL SELECT 2) As CJ
LEFT JOIN picture p ON p.user_id = u.id AND CJ.C1 = 1

这会使用交叉连接复制用户表,然后将图片附加到其中一个副本

如果您不需要额外的Drosso | NULL,那么简单的左连接就可以了

答案 1 :(得分:0)

我所取得的最佳优化是使用“物化视图”并应用所需的索引。过去使用~0.4000 sec的查询现在需要~0.0025 sec

MySQL不支持物化视图,因此我必须手动创建表格表和触发器(这不是很好,但在我的情况下值得做)。