有没有比使用 UNION 更好的方法来组合两个查询?
Is there a better way to combine two queries other than using UNION?
我有两个相同的查询。我有一个案例,我想获取与一个集合相关的所有订单。我可以考虑使用 UNION 但是它太慢了。
查询 1:
在这里,我试图查询具有类型 2 的订单,这意味着 ref_id 正在引用一个变体。
订单 -> order_items -> varaints -> 产品 -> 行 -> 系列
SELECT
`orders`.*
FROM
`orders`
LEFT JOIN `order_items` ON `orders`.`id` = `order_items`.`order_id`
LEFT JOIN `variants` ON `order_items`.`ref_id` = `variants`.`id`
LEFT JOIN `line_products` ON `variants`.`parent_id` = `line_products`.`product_id`
AND `order_items`.`type` = 2
LEFT JOIN `collection_line` ON `line_products`.`line_id` = `collection_line`.`line_id`
WHERE
`collection_line`.`collection_id` = 55;
查询 2:
在这里,我试图查询商品类型为 1 的订单,这意味着 ref_id 正在引用产品。
订单 -> order_items -> 产品 -> 行 -> 系列
SELECT
`orders`.*
FROM
`orders`
LEFT JOIN `order_items` ON `orders`.`id` = `order_items`.`order_id`
LEFT JOIN `line_products` ON `order_items`.`ref_id` = `line_products`.`product_id`
AND `order_items`.`type` = 1
LEFT JOIN `collection_line` ON `line_products`.`line_id` = `collection_line`.`line_id`
WHERE
`collection_line`.`collection_id` = 55;
有什么方法可以组合和优化这两个查询吗?
您可以试试这个查询。
SELECT
`orders`.*
FROM
`orders`
LEFT JOIN `order_items` ON `orders`.`id` = `order_items`.`order_id`
LEFT JOIN `variants` ON `order_items`.`ref_id` = `variants`.`id`
LEFT JOIN `line_products` ON `variants`.`parent_id` = `line_products`.`product_id`
AND `order_items`.`type` IN ('1', '2')
LEFT JOIN `collection_line` ON `line_products`.`line_id` = `collection_line`.`line_id`
WHERE
`collection_line`.`collection_id` = 55;
使用IN
collection_line
听起来像是多对多映射 table。如果是这样,请遵循此处的索引建议:http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table 特别是,需要 (collection_id, line_id)
上的复合索引。
line_products
.
同样
p
需要 (line_id, product_id)
i
: (ref_id, type, order_id)
LEFT
可能是不必要的;看看没有它是否能得到相同的结果。
这适用于单个订单,并且正在进行双左连接。一个用于变体,第二个用于默认行产品/系列。您让 WHERE 子句的每个实例都包含“collection_id = 55”,它出于需求目的将左联接更改为 INNER 联接。
因此,使用一个根级命令 table 两个左连接可以同时进行。唯一要添加的是“WHERE”子句。所以,无论NOT null的条件是哪个,都应该是一个或另一个。
select
o.*
from
( SELECT DISTINCT
oi.order_id
FROM
order_items oi
LEFT JOIN variants v
ON oi.ref_id = v.id
AND oi.type = 2
LEFT JOIN line_products lp
ON v.parent_id = lp.product_id
LEFT JOIN collection_line cl
ON lp.line_id = cl.line_id
AND cl.collection_id = 55;
LEFT JOIN line_products lp2
ON oi2.ref_id = lp2.product_id
AND oi2.type = 1
LEFT JOIN collection_line cl2
ON lp2.line_id = cl2.line_id
AND cl2.collection_id = 55
where
oi.type in ( 1, 2 )
AND ( cl.collection_id = 55
OR cl2.collection_id = 55 )) PQ
JOIN Orders o
on PQ.order_id = o.id
通过 OR,两边都不需要,但只要其中之一符合条件,顺序就应该 return。由于连接可能会为同一订单创建多个 return,并且您没有拉取状态。然后将这些唯一 ID 加入订单 table
我有两个相同的查询。我有一个案例,我想获取与一个集合相关的所有订单。我可以考虑使用 UNION 但是它太慢了。
查询 1: 在这里,我试图查询具有类型 2 的订单,这意味着 ref_id 正在引用一个变体。
订单 -> order_items -> varaints -> 产品 -> 行 -> 系列
SELECT
`orders`.*
FROM
`orders`
LEFT JOIN `order_items` ON `orders`.`id` = `order_items`.`order_id`
LEFT JOIN `variants` ON `order_items`.`ref_id` = `variants`.`id`
LEFT JOIN `line_products` ON `variants`.`parent_id` = `line_products`.`product_id`
AND `order_items`.`type` = 2
LEFT JOIN `collection_line` ON `line_products`.`line_id` = `collection_line`.`line_id`
WHERE
`collection_line`.`collection_id` = 55;
查询 2: 在这里,我试图查询商品类型为 1 的订单,这意味着 ref_id 正在引用产品。
订单 -> order_items -> 产品 -> 行 -> 系列
SELECT
`orders`.*
FROM
`orders`
LEFT JOIN `order_items` ON `orders`.`id` = `order_items`.`order_id`
LEFT JOIN `line_products` ON `order_items`.`ref_id` = `line_products`.`product_id`
AND `order_items`.`type` = 1
LEFT JOIN `collection_line` ON `line_products`.`line_id` = `collection_line`.`line_id`
WHERE
`collection_line`.`collection_id` = 55;
有什么方法可以组合和优化这两个查询吗?
您可以试试这个查询。
SELECT
`orders`.*
FROM
`orders`
LEFT JOIN `order_items` ON `orders`.`id` = `order_items`.`order_id`
LEFT JOIN `variants` ON `order_items`.`ref_id` = `variants`.`id`
LEFT JOIN `line_products` ON `variants`.`parent_id` = `line_products`.`product_id`
AND `order_items`.`type` IN ('1', '2')
LEFT JOIN `collection_line` ON `line_products`.`line_id` = `collection_line`.`line_id`
WHERE
`collection_line`.`collection_id` = 55;
使用IN
collection_line
听起来像是多对多映射 table。如果是这样,请遵循此处的索引建议:http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table 特别是,需要 (collection_id, line_id)
上的复合索引。
line_products
.
p
需要 (line_id, product_id)
i
: (ref_id, type, order_id)
LEFT
可能是不必要的;看看没有它是否能得到相同的结果。
这适用于单个订单,并且正在进行双左连接。一个用于变体,第二个用于默认行产品/系列。您让 WHERE 子句的每个实例都包含“collection_id = 55”,它出于需求目的将左联接更改为 INNER 联接。
因此,使用一个根级命令 table 两个左连接可以同时进行。唯一要添加的是“WHERE”子句。所以,无论NOT null的条件是哪个,都应该是一个或另一个。
select
o.*
from
( SELECT DISTINCT
oi.order_id
FROM
order_items oi
LEFT JOIN variants v
ON oi.ref_id = v.id
AND oi.type = 2
LEFT JOIN line_products lp
ON v.parent_id = lp.product_id
LEFT JOIN collection_line cl
ON lp.line_id = cl.line_id
AND cl.collection_id = 55;
LEFT JOIN line_products lp2
ON oi2.ref_id = lp2.product_id
AND oi2.type = 1
LEFT JOIN collection_line cl2
ON lp2.line_id = cl2.line_id
AND cl2.collection_id = 55
where
oi.type in ( 1, 2 )
AND ( cl.collection_id = 55
OR cl2.collection_id = 55 )) PQ
JOIN Orders o
on PQ.order_id = o.id
通过 OR,两边都不需要,但只要其中之一符合条件,顺序就应该 return。由于连接可能会为同一订单创建多个 return,并且您没有拉取状态。然后将这些唯一 ID 加入订单 table