使用 UNION 优化 MySQL 查询
Optimize a MySQL query with UNIONs
我需要 运行 一个包含多个 UNION 的长 MySQL 查询。一些子查询花费了很多时间,导致 运行 时间很长。我已经在表上创建了索引,但到 运行 仍然需要大约 15 秒。我需要将 运行 时间减少到 1 秒。
这里是查询:
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color, NULL AS Ink_Type, NULL AS Industry,
NULL AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, NULL AS Material, NULL AS Pattern, NULL AS Country_Origin, NULL AS Ships_From, pi.prd_img_name
FROM products p
LEFT JOIN product_image_p pi ON p.prd_id = pi.prd_id
WHERE p.is_deleted = 'no'
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
NULL AS Ink_Type, NULL AS Industry, NULL AS Size, GROUP_CONCAT(decoration.dm_name SEPARATOR ', ') AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, NULL AS Material,
NULL AS Pattern, NULL AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_dm pdm ON pdm.prd_id = p.prd_id
JOIN decoration_method decoration ON decoration.dm_id = pdm.dm_id
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
NULL AS Ink_Type, NULL AS Industry, NULL AS Size, NULL AS Decoration_Method, GROUP_CONCAT(rush.rush_title SEPARATOR ', ') AS Rush_Production, NULL AS Themes, NULL AS Material,
NULL AS Pattern, NULL AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_rush_title prt ON prt.prd_id = p.prd_id
JOIN rush_title rush ON rush.rush_id = prt.rush_id
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, GROUP_CONCAT(ao.option_name SEPARATOR ', ') AS Item_Color,
NULL AS Ink_Type, NULL AS Industry, NULL AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, NULL AS Material, NULL AS Pattern,
NULL AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_attributes pa ON pa.prd_id = p.prd_id
JOIN attributes_options ao ON ao.attr_opt_id = pa.attr_opt_id AND ao.attr_id = 19
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
GROUP_CONCAT(ao.option_name SEPARATOR ', ') AS Ink_Type, NULL AS Industry, NULL AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, NULL AS Material,
NULL AS Pattern, NULL AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_attributes pa ON pa.prd_id = p.prd_id
JOIN attributes_options ao ON ao.attr_opt_id = pa.attr_opt_id AND ao.attr_id = 10
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
NULL AS Ink_Type, GROUP_CONCAT(ao.option_name SEPARATOR ', ') AS Industry, NULL AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, NULL AS Material,
NULL AS Pattern, NULL AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_attributes pa ON pa.prd_id = p.prd_id
JOIN attributes_options ao ON ao.attr_opt_id = pa.attr_opt_id AND ao.attr_id = 18
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
NULL AS Ink_Type, NULL AS Industry, GROUP_CONCAT(ao.option_name SEPARATOR ', ') AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, NULL AS Material,
NULL AS Pattern, NULL AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_attributes pa ON pa.prd_id = p.prd_id
JOIN attributes_options ao ON ao.attr_opt_id = pa.attr_opt_id AND ao.attr_id IN (1, 13, 14)
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
NULL AS Ink_Type, NULL AS Industry, NULL AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, GROUP_CONCAT(ao.option_name) AS Themes,
NULL AS Material, NULL AS Pattern, NULL AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_attributes pa ON pa.prd_id = p.prd_id
JOIN attributes_options ao ON ao.attr_opt_id = pa.attr_opt_id AND ao.attr_id = 17
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
NULL AS Ink_Type, NULL AS Industry, NULL AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, GROUP_CONCAT(ao.option_name) AS Material,
NULL AS Pattern, NULL AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_attributes pa ON pa.prd_id = p.prd_id
JOIN attributes_options ao ON ao.attr_opt_id = pa.attr_opt_id AND ao.attr_id = 12
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
NULL AS Ink_Type, NULL AS Industry, NULL AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, NULL AS Material,
GROUP_CONCAT(ao.option_name) AS Pattern, NULL AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_attributes pa ON pa.prd_id = p.prd_id
JOIN attributes_options ao ON ao.attr_opt_id = pa.attr_opt_id AND ao.attr_id = 2
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
NULL AS Ink_Type, NULL AS Industry, NULL AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, NULL AS Material,
NULL AS Pattern, GROUP_CONCAT(ao.option_name) AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_attributes pa ON pa.prd_id = p.prd_id
JOIN attributes_options ao ON ao.attr_opt_id = pa.attr_opt_id AND ao.attr_id = 11
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
NULL AS Ink_Type, NULL AS Industry, NULL AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, NULL AS Material,
NULL AS Pattern, NULL AS Country_Origin, GROUP_CONCAT(ao.option_name) AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_attributes pa ON pa.prd_id = p.prd_id
JOIN attributes_options ao ON ao.attr_opt_id = pa.attr_opt_id AND ao.attr_id = 8
WHERE p.is_deleted = 'no'
group by prd_id
您遇到的问题是重复加入产品属性和产品选项并进行完整查询并为您要查找的每个组件获取一条记录 returned。此外,对于来自选项 table 的所有部分,您可以为每个产品 pre-query 一次,然后 return 每个组件作为相关 PRD_ID 的一条记录.
为了帮助优化该组件,我强烈建议(如果还没有的话)以下索引...
Table Index
product_attributes ( prd_id, attr_opt_id )
attributes_options ( attr_opt_id, attr_id, option_name )
products ( is_deleted, prd_id )
product_dm ( prd_id, dm_id )
decoration_method ( dm_id, dm_name )
product_rush_title ( prd_id, rush_id )
rush_title ( rush_id, rush_title )
索引将是 "covering" 个索引,因此系统不必返回原始数据页来为其中的大部分准备结果
然后,要将每个部分作为内部 pre-query 执行类似...
由于装饰和抢购内容来自其他table,也可以仅根据产品ID进行预查询和汇总,然后left-joined
SELECT
p2.prd_id,
GROUP_CONCAT( case when ao.attr_id = 19
then ao.option_name else null end SEPARATOR ', ')
AS Item_Color,
GROUP_CONCAT( case when ao.attr_id = 10
then ao.option_name else null end SEPARATOR ', ')
AS Ink_Type,
GROUP_CONCAT( case when ao.attr_id = 18
then ao.option_name else null end SEPARATOR ', ')
AS Industry,
GROUP_CONCAT( case when ao.attr_id = 17
then ao.option_name else null end SEPARATOR ', ')
AS Themes,
GROUP_CONCAT( case when ao.attr_id = 12
then ao.option_name else null end SEPARATOR ', ')
AS Material,
GROUP_CONCAT( case when ao.attr_id = 2
then ao.option_name else null end SEPARATOR ', ')
AS Pattern,
GROUP_CONCAT( case when ao.attr_id = 11
then ao.option_name else null end SEPARATOR ', ')
AS Country_Origin,
GROUP_CONCAT( case when ao.attr_id = 8
then ao.option_name else null end SEPARATOR ', ')
AS Ships_From,
GROUP_CONCAT( case when ao.attr_id IN ( 1, 13, 14 )
then ao.option_name else null end SEPARATOR ', ')
AS Size
from
products p2
JOIN product_attributes pa
ON p2.prd_id = pa.prd_id
JOIN attributes_options ao
ON pa.attr_opt_id = ao.attr_opt_id
WHERE
p2.is_deleted = 'no'
group by
p2.prd_id
然后您可以将整个查询作为子查询滚动到您的主查询中,但使用简化的别名引用和每个 pre-group concat 字段结果
SELECT
p.prd_id,
NULL AS manu_name,
NULL AS brand_name,
NULL AS Categories,
preQuery.Item_Color,
preQuery.Ink_Type,
preQuery.Industry,
preQuery.Themes,
preQuery.Material,
preQuery.Pattern,
preQuery.Country_Origin,
preQuery.Ships_From,
preQuery.Size,
tmpDeco.Decoration_Method,
tmpRush.Rush_Production,
pi.prd_img_name
FROM
products p
LEFT JOIN product_image_p pi
ON p.prd_id = pi.prd_id
LEFT JOIN
( THE PRE-QUERY SAMPLE ABOVE ) PreQuery
ON p.prd_id = PreQuery.prd_id
LEFT JOIN
( select
p2.prd_id,
GROUP_CONCAT(decoration.dm_name SEPARATOR ', ') AS Decoration_Method
FROM
products p2
JOIN product_dm pdm
ON p2.prd_id = pdm.prd_id
JOIN decoration_method decoration ;
ON decoration.dm_id = pdm.dm_id
WHERE
p2.is_deleted = 'no'
group by
p2.prd_id ) as tmpDeco
ON p.prd_id = tmpDeco.prd_id
LEFT JOIN
( select
p2.prd_id,
GROUP_CONCAT(rush.rush_title SEPARATOR ', ') AS Rush_Production
FROM
products p2
JOIN product_rush_title prt
ON p2.prd_id = prt.prd_id
JOIN rush_title rush
ON prt.rush_id = rush.rush_id
WHERE
p2.is_deleted = 'no'
group by
p2.prd_id ) as tmpRush
ON p.prd_id = tmpRush.prd_id
WHERE
p.is_deleted = 'no'
希望您能够看到简化的上下文,即同时获取源自同一 table 的所有常见描述元素,然后在基于单个别名引用完成后加入。
我可能有一两个 type-o,但根据您的需要,我认为它是正确的。您也没有 Manu_Name、Brand_Name 类别的任何内容,因此您必须完成该组件。
FOLLOW-UP...
根据您的最新消息,我会为您的产品添加一些字段 table 以保存每个字段。然后,为产品添加 insert/update/delete 到产品属性 table 的触发器。当发生影响时,运行 只需简单地 sql-select group_concat() 在有问题的字段上并立即更新主要产品 table。是的,这在一定程度上进行了非规范化,但完全简化了执行密集查询和降低性能的需求。
看看我的回答。我正在创建这样一个类似的触发器。这样,您的主要 table 已经 pre-aggregated 并准备就绪,并且触发器应该几乎立即运行,因为您只会为单个产品执行单个字段。
部分性能问题可能是由于"over-normalization"。注意 GROUP_CONCAT(ao.option_name)
不是来自属性 table,而是通过另一个 JOIN
。建议你摆脱 ao
并将 option_names
移动到 product_attributes
.
(这是对@DRapp 的回答的补充,从表面上看,它似乎涵盖了查询中的许多问题。)
我需要 运行 一个包含多个 UNION 的长 MySQL 查询。一些子查询花费了很多时间,导致 运行 时间很长。我已经在表上创建了索引,但到 运行 仍然需要大约 15 秒。我需要将 运行 时间减少到 1 秒。
这里是查询:
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color, NULL AS Ink_Type, NULL AS Industry,
NULL AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, NULL AS Material, NULL AS Pattern, NULL AS Country_Origin, NULL AS Ships_From, pi.prd_img_name
FROM products p
LEFT JOIN product_image_p pi ON p.prd_id = pi.prd_id
WHERE p.is_deleted = 'no'
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
NULL AS Ink_Type, NULL AS Industry, NULL AS Size, GROUP_CONCAT(decoration.dm_name SEPARATOR ', ') AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, NULL AS Material,
NULL AS Pattern, NULL AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_dm pdm ON pdm.prd_id = p.prd_id
JOIN decoration_method decoration ON decoration.dm_id = pdm.dm_id
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
NULL AS Ink_Type, NULL AS Industry, NULL AS Size, NULL AS Decoration_Method, GROUP_CONCAT(rush.rush_title SEPARATOR ', ') AS Rush_Production, NULL AS Themes, NULL AS Material,
NULL AS Pattern, NULL AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_rush_title prt ON prt.prd_id = p.prd_id
JOIN rush_title rush ON rush.rush_id = prt.rush_id
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, GROUP_CONCAT(ao.option_name SEPARATOR ', ') AS Item_Color,
NULL AS Ink_Type, NULL AS Industry, NULL AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, NULL AS Material, NULL AS Pattern,
NULL AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_attributes pa ON pa.prd_id = p.prd_id
JOIN attributes_options ao ON ao.attr_opt_id = pa.attr_opt_id AND ao.attr_id = 19
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
GROUP_CONCAT(ao.option_name SEPARATOR ', ') AS Ink_Type, NULL AS Industry, NULL AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, NULL AS Material,
NULL AS Pattern, NULL AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_attributes pa ON pa.prd_id = p.prd_id
JOIN attributes_options ao ON ao.attr_opt_id = pa.attr_opt_id AND ao.attr_id = 10
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
NULL AS Ink_Type, GROUP_CONCAT(ao.option_name SEPARATOR ', ') AS Industry, NULL AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, NULL AS Material,
NULL AS Pattern, NULL AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_attributes pa ON pa.prd_id = p.prd_id
JOIN attributes_options ao ON ao.attr_opt_id = pa.attr_opt_id AND ao.attr_id = 18
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
NULL AS Ink_Type, NULL AS Industry, GROUP_CONCAT(ao.option_name SEPARATOR ', ') AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, NULL AS Material,
NULL AS Pattern, NULL AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_attributes pa ON pa.prd_id = p.prd_id
JOIN attributes_options ao ON ao.attr_opt_id = pa.attr_opt_id AND ao.attr_id IN (1, 13, 14)
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
NULL AS Ink_Type, NULL AS Industry, NULL AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, GROUP_CONCAT(ao.option_name) AS Themes,
NULL AS Material, NULL AS Pattern, NULL AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_attributes pa ON pa.prd_id = p.prd_id
JOIN attributes_options ao ON ao.attr_opt_id = pa.attr_opt_id AND ao.attr_id = 17
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
NULL AS Ink_Type, NULL AS Industry, NULL AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, GROUP_CONCAT(ao.option_name) AS Material,
NULL AS Pattern, NULL AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_attributes pa ON pa.prd_id = p.prd_id
JOIN attributes_options ao ON ao.attr_opt_id = pa.attr_opt_id AND ao.attr_id = 12
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
NULL AS Ink_Type, NULL AS Industry, NULL AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, NULL AS Material,
GROUP_CONCAT(ao.option_name) AS Pattern, NULL AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_attributes pa ON pa.prd_id = p.prd_id
JOIN attributes_options ao ON ao.attr_opt_id = pa.attr_opt_id AND ao.attr_id = 2
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
NULL AS Ink_Type, NULL AS Industry, NULL AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, NULL AS Material,
NULL AS Pattern, GROUP_CONCAT(ao.option_name) AS Country_Origin, NULL AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_attributes pa ON pa.prd_id = p.prd_id
JOIN attributes_options ao ON ao.attr_opt_id = pa.attr_opt_id AND ao.attr_id = 11
WHERE p.is_deleted = 'no'
group by prd_id
UNION
SELECT p.prd_id, NULL AS manu_name, NULL AS brand_name, NULL AS Categories, NULL AS Item_Color,
NULL AS Ink_Type, NULL AS Industry, NULL AS Size, NULL AS Decoration_Method, NULL AS Rush_Production, NULL AS Themes, NULL AS Material,
NULL AS Pattern, NULL AS Country_Origin, GROUP_CONCAT(ao.option_name) AS Ships_From, NULL AS prd_img_name
FROM products p
JOIN product_attributes pa ON pa.prd_id = p.prd_id
JOIN attributes_options ao ON ao.attr_opt_id = pa.attr_opt_id AND ao.attr_id = 8
WHERE p.is_deleted = 'no'
group by prd_id
您遇到的问题是重复加入产品属性和产品选项并进行完整查询并为您要查找的每个组件获取一条记录 returned。此外,对于来自选项 table 的所有部分,您可以为每个产品 pre-query 一次,然后 return 每个组件作为相关 PRD_ID 的一条记录.
为了帮助优化该组件,我强烈建议(如果还没有的话)以下索引...
Table Index
product_attributes ( prd_id, attr_opt_id )
attributes_options ( attr_opt_id, attr_id, option_name )
products ( is_deleted, prd_id )
product_dm ( prd_id, dm_id )
decoration_method ( dm_id, dm_name )
product_rush_title ( prd_id, rush_id )
rush_title ( rush_id, rush_title )
索引将是 "covering" 个索引,因此系统不必返回原始数据页来为其中的大部分准备结果
然后,要将每个部分作为内部 pre-query 执行类似...
由于装饰和抢购内容来自其他table,也可以仅根据产品ID进行预查询和汇总,然后left-joined
SELECT
p2.prd_id,
GROUP_CONCAT( case when ao.attr_id = 19
then ao.option_name else null end SEPARATOR ', ')
AS Item_Color,
GROUP_CONCAT( case when ao.attr_id = 10
then ao.option_name else null end SEPARATOR ', ')
AS Ink_Type,
GROUP_CONCAT( case when ao.attr_id = 18
then ao.option_name else null end SEPARATOR ', ')
AS Industry,
GROUP_CONCAT( case when ao.attr_id = 17
then ao.option_name else null end SEPARATOR ', ')
AS Themes,
GROUP_CONCAT( case when ao.attr_id = 12
then ao.option_name else null end SEPARATOR ', ')
AS Material,
GROUP_CONCAT( case when ao.attr_id = 2
then ao.option_name else null end SEPARATOR ', ')
AS Pattern,
GROUP_CONCAT( case when ao.attr_id = 11
then ao.option_name else null end SEPARATOR ', ')
AS Country_Origin,
GROUP_CONCAT( case when ao.attr_id = 8
then ao.option_name else null end SEPARATOR ', ')
AS Ships_From,
GROUP_CONCAT( case when ao.attr_id IN ( 1, 13, 14 )
then ao.option_name else null end SEPARATOR ', ')
AS Size
from
products p2
JOIN product_attributes pa
ON p2.prd_id = pa.prd_id
JOIN attributes_options ao
ON pa.attr_opt_id = ao.attr_opt_id
WHERE
p2.is_deleted = 'no'
group by
p2.prd_id
然后您可以将整个查询作为子查询滚动到您的主查询中,但使用简化的别名引用和每个 pre-group concat 字段结果
SELECT
p.prd_id,
NULL AS manu_name,
NULL AS brand_name,
NULL AS Categories,
preQuery.Item_Color,
preQuery.Ink_Type,
preQuery.Industry,
preQuery.Themes,
preQuery.Material,
preQuery.Pattern,
preQuery.Country_Origin,
preQuery.Ships_From,
preQuery.Size,
tmpDeco.Decoration_Method,
tmpRush.Rush_Production,
pi.prd_img_name
FROM
products p
LEFT JOIN product_image_p pi
ON p.prd_id = pi.prd_id
LEFT JOIN
( THE PRE-QUERY SAMPLE ABOVE ) PreQuery
ON p.prd_id = PreQuery.prd_id
LEFT JOIN
( select
p2.prd_id,
GROUP_CONCAT(decoration.dm_name SEPARATOR ', ') AS Decoration_Method
FROM
products p2
JOIN product_dm pdm
ON p2.prd_id = pdm.prd_id
JOIN decoration_method decoration ;
ON decoration.dm_id = pdm.dm_id
WHERE
p2.is_deleted = 'no'
group by
p2.prd_id ) as tmpDeco
ON p.prd_id = tmpDeco.prd_id
LEFT JOIN
( select
p2.prd_id,
GROUP_CONCAT(rush.rush_title SEPARATOR ', ') AS Rush_Production
FROM
products p2
JOIN product_rush_title prt
ON p2.prd_id = prt.prd_id
JOIN rush_title rush
ON prt.rush_id = rush.rush_id
WHERE
p2.is_deleted = 'no'
group by
p2.prd_id ) as tmpRush
ON p.prd_id = tmpRush.prd_id
WHERE
p.is_deleted = 'no'
希望您能够看到简化的上下文,即同时获取源自同一 table 的所有常见描述元素,然后在基于单个别名引用完成后加入。
我可能有一两个 type-o,但根据您的需要,我认为它是正确的。您也没有 Manu_Name、Brand_Name 类别的任何内容,因此您必须完成该组件。
FOLLOW-UP...
根据您的最新消息,我会为您的产品添加一些字段 table 以保存每个字段。然后,为产品添加 insert/update/delete 到产品属性 table 的触发器。当发生影响时,运行 只需简单地 sql-select group_concat() 在有问题的字段上并立即更新主要产品 table。是的,这在一定程度上进行了非规范化,但完全简化了执行密集查询和降低性能的需求。
看看我的回答
部分性能问题可能是由于"over-normalization"。注意 GROUP_CONCAT(ao.option_name)
不是来自属性 table,而是通过另一个 JOIN
。建议你摆脱 ao
并将 option_names
移动到 product_attributes
.
(这是对@DRapp 的回答的补充,从表面上看,它似乎涵盖了查询中的许多问题。)