【发布时间】:2015-03-05 19:34:16
【问题描述】:
有一些类似的问题,但没有一个符合我的情况。
SQL Optimization - Join different tables based on column value
How to JOIN on different tables based on column value
MySQL query to JOIN tables based on column values
MySQL: Use CASE/ELSE value as join parameter
MySQL query where JOIN depends on CASE
我有这种结构的通知表
CREATE TABLE `notifications` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`notificaiton_type_id` int(11) DEFAULT NULL,
`table1_id` int(11) DEFAULT NULL,
`table2_id` int(11) DEFAULT NULL,
`table3_id` int(11) DEFAULT NULL,
`table4_id` int(11) DEFAULT NULL,
`table5_id` int(11) DEFAULT NULL,
`user_id` int(11) DEFAULT NULL,
`created` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `userIdIndex` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
和 5 个表,从 table1 到 table5,具有这些结构(其他相同:我将其设置为测试,不确定是否重要,但除了发布的字段之外,这些表(1 到 5)还有其他字段好吧,只是他们不参与查询,所以为了简单起见,我只是跳过了他们)
CREATE TABLE `table1` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(300) COLLATE utf8_bin DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
table*_id 是表的外键:table1 - table5 具有一对多关系。
我应该根据user_id 选择通知。根据通知类型,适当的 table*_id 有一些值,其他 foreign_keys 为 null(顺便说一下,有 2 个甚至 3 个 table *_id 可以与 null 不同的通知类型)。最初的想法是,如果外键通过使用 CASE、WHEN 具有与 null 不同的某些值,则只有一个查询将连接这些表,但正如我从这个问题的答案中了解到的那样,
MySQL query where JOIN depends on CASE
在这种情况下不能使用。
表 table1-table5 会比较大,有几百万或几千万条记录。因此,如果外键为空,我不希望加入额外的 2-4 个表。另外,我不认为将查询分成 2 个主要部分更好,例如 - 首先获取通知,然后在循环中查找关联表的值。
所以,关键是只加入那些table*_id不为空的表,如果它可以在mysql中完成。
主要问题是实现这一目标的最有效方法是什么 - 获取通知信息及其相关表格数据。
连接所有表的一般查询是一个普通的左连接,像这样
EXPLAIN SELECT
n.`id`,
n.`user_id`,
n.`table1_id`,
n.`table2_id`,
n.`table3_id`,
n.`table4_id`,
n.`table5_id`
// other fields
FROM
notifications AS n
LEFT JOIN table1 AS t1
ON t1.`id` = n.`table1_id`
LEFT JOIN table2 AS t2
ON t2.`id` = n.`table2_id`
LEFT JOIN table3 AS t3
ON t3.`id` = n.`table3_id`
LEFT JOIN table4 AS t4
ON t4.`id` = n.`table4_id`
LEFT JOIN table5 AS t5
ON t5.`id` = n.`table5_id`
WHERE user_id = 5
这里是 sql fiddle with data http://sqlfiddle.com/#!2/3bf8f/1/0
谢谢
【问题讨论】:
标签: mysql join query-optimization