假设我有这个问题:
(SELECT pets.id, "pets" AS "table" FROM pets WHERE name="Joey")
UNION ALL
(SELECT toys.id, "toys" AS "table" FROM (SELECT id, "pets" AS "table" FROM pets WHERE name="Joey") AS parentQuery, toys WHERE type="Ball" AND pet_id=parentQuery.id)
UNION ALL
(SELECT owners.id, "owners" AS "table" FROM (SELECT id, "pets" AS "table" FROM pets WHERE name="Joey") AS parentQuery, owners WHERE name="Issac" AND pet_id=parentQuery.id)
SQL小提琴:http://sqlfiddle.com/#!9/1637a/1
这里的想法是在多个一对多场景中获取相关行的ID列。 几个问题:
UNION
'ed查询中,是否可以安全地进行查询干净地使用 SQL变量 (或其他东西)来引用其他查询中第一个查询的结果...以避免再次重复查询和任何捆绑参数每个额外的UNION
'ed查询?JOIN
变体来完成,但是我不确定是否会通过大量连接来提高性能,而不仅仅是像这样分割它?我听到了不同的意见。谢谢!我已经看到了这个响应并且认为类似的东西可以工作,但是我到目前为止一般都避免使用SQL变量,因此我不确定如何使用UNION
'ed查询来构建它:{{3} }
答案 0 :(得分:0)
我想补充一些其他内容。
1)使用inner join
转换您的查询。
我个人认为INNER JOIN更好,因为它更多 可读。 它更好地显示了表格之间的关系。你得到了 在连接中的那些关系,并在WHERE中进行过滤 条款。这种分离使查询更具可读性。但这是一个 个人品味问题。
因此,根据此选择,您转换后的查询:
SELECT
pets.id,
"pets" AS "table"
FROM pets
WHERE name= "Joey"
UNION ALL
SELECT
owners.id,
"pets" AS "table"
FROM pets
INNER JOIN owners ON pets.id = owners.pet_id
WHERE pets.`name` = "Joey"
AND owners.`name`= "Issac"
UNION ALL
SELECT
toys.id,
"toys" AS "table"
FROM toys
INNER JOIN pets ON toys.pet_id = pets.id
WHERE pets.Name="Joey"
AND toys.type="Ball";
2)虽然您当前的查询效果不错,但我认为您可以通过在表格中创建一些composite index
来提升效果。
pets
表需要name,id
上的综合索引。toys
表需要pet_id,type
上的综合索引。owners
表需要pet_id,name
上的综合索引。修改强>
以下是创建了上述索引的三个表的表结构。
-- ----------------------------
-- Table structure for `owners`
-- ----------------------------
DROP TABLE IF EXISTS `owners`;
CREATE TABLE `owners` (
`id` bigint(20) DEFAULT NULL,
`pet_id` bigint(20) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
KEY `Idx_owners_pet_id_name` (`pet_id`,`name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for `pets`
-- ----------------------------
DROP TABLE IF EXISTS `pets`;
CREATE TABLE `pets` (
`id` bigint(20) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
KEY `Idx_pets_name_pet_id` (`name`,`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for `toys`
-- ----------------------------
DROP TABLE IF EXISTS `toys`;
CREATE TABLE `toys` (
`id` bigint(20) DEFAULT NULL,
`pet_id` bigint(20) DEFAULT NULL,
`type` varchar(255) DEFAULT NULL,
KEY `Idx_toys_pet_id_type` (`pet_id`,`type`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
注意:稍后您可以按EXPLAIN (MySQL)
检查查询效果。确保这三个表中有大量数据。 因为您无法判断小数据集的效果。