Sql oracle中的查询优化
我需要从两列上连接的一个表和一个视图中获取结果 查看:800万条记录 表:5K记录 我查看了查询计划,发现查询将需要很长时间才能运行,实际上,我尝试运行此查询,但没有得到任何结果 请帮助我优化查询。我没有使用任何提示Sql oracle中的查询优化,sql,oracle,join,Sql,Oracle,Join,我需要从两列上连接的一个表和一个视图中获取结果 查看:800万条记录 表:5K记录 我查看了查询计划,发现查询将需要很长时间才能运行,实际上,我尝试运行此查询,但没有得到任何结果 请帮助我优化查询。我没有使用任何提示 SELECT coupon_upc , sum ( loyalty_a ) a , sum ( loyalty_b ) b , sum ( loyalty_c ) c , sum ( loyalty_x ) FROM ( SELECT c
SELECT coupon_upc
, sum ( loyalty_a ) a
, sum ( loyalty_b ) b
, sum ( loyalty_c ) c
, sum ( loyalty_x )
FROM ( SELECT ccd.coupon_upc AS coupon_upc
, ( CASE WHEN a.loyalty_cell = 'A' then 1 else 0 end ) AS loyalty_a
, ( CASE WHEN a.loyalty_cell = 'B' then 1 else 0 end ) AS loyalty_b
, ( CASE WHEN a.loyalty_cell = 'C1' then 1 else 0 end ) AS loyalty_c
, ( CASE WHEN a.loyalty_cell = 'X' then 1 else 0 end ) AS loyalty_x
FROM view1 a
, ( select distinct coupon_upc
, coupon_id
, division
from table2
where schedule_key = 'XXX' ) ccd
WHERE a.campaign_code = 'XXX'
AND a.coupon_id = ccd.coupon_id
AND a.division = ccd.division ) a
GROUP BY coupon_upc
没有解释计划或模式/DDL,可以进行的优化数量是有限的 这里有一个替代方案,但您需要测试它,看看它是否有任何区别。(用相关子查询替换联接。) 除此之外,这种优化是:
-持久化视图
-索引
-重构数据结构 编辑 查询的另一个可能重构。。。我不知道Oracle会如何优化相关子查询的4个实例
SELECT
coupon_upc,
SUM((SELECT COUNT(*) FROM view1 WHERE campaign_code = 'XXX' AND loyalty_cell = 'A' AND coupon_id = map.coupon_id AND division = map.division)) AS loyalty_a,
SUM((SELECT COUNT(*) FROM view1 WHERE campaign_code = 'XXX' AND loyalty_cell = 'B' AND coupon_id = map.coupon_id AND division = map.division)) AS loyalty_b,
SUM((SELECT COUNT(*) FROM view1 WHERE campaign_code = 'XXX' AND loyalty_cell = 'C1' AND coupon_id = map.coupon_id AND division = map.division)) AS loyalty_c,
SUM((SELECT COUNT(*) FROM view1 WHERE campaign_code = 'XXX' AND loyalty_cell = 'X' AND coupon_id = map.coupon_id AND division = map.division)) AS loyalty_x
FROM
(
SELECT coupon_upc, coupon_id, division
FROM table2 WHERE schedule_key = 'xxx'
GROUP BY coupon_upc, coupon_id, division
)
AS map
GROUP BY
coupon_upc
或者也许
SELECT
map.coupon_upc, SUM(data.loyalty_a) AS a, SUM(data.loyalty_b) AS b, SUM(data.loyalty_c) AS c, SUM(data.loyalty_x) AS X
FROM
(
SELECT coupon_upc, coupon_id, division
FROM table2 WHERE schedule_key = 'xxx'
GROUP BY coupon_upc, coupon_id, division
)
AS map
INNER JOIN
(
SELECT
coupon_id,
division,
SUM(CASE WHEN loyalty_cell = 'A' THEN 1 ELSE 0 END) AS loyalty_a,
SUM(CASE WHEN loyalty_cell = 'B' THEN 1 ELSE 0 END) AS loyalty_b,
SUM(CASE WHEN loyalty_cell = 'C1' THEN 1 ELSE 0 END) AS loyalty_c,
SUM(CASE WHEN loyalty_cell = 'X' THEN 1 ELSE 0 END) AS loyalty_x
FROM
view1
WHERE
campaign_code = 'XXX'
)
AS data
ON data.coupon_id = map.coupon_id
AND data.division = map.division
GROUP BY
map.coupon_upc
另一种可能的重写是:
SELECT
map.coupon_upc
, COUNT(CASE WHEN a.loyalty_cell = 'A' THEN 1 ELSE NULL END) AS loyalty_a
, COUNT(CASE WHEN a.loyalty_cell = 'B' THEN 1 ELSE NULL END) AS loyalty_b
, COUNT(CASE WHEN a.loyalty_cell = 'C1' THEN 1 ELSE NULL END) AS loyalty_c
, COUNT(CASE WHEN a.loyalty_cell = 'X' THEN 1 ELSE NULL END) AS loyalty_x
FROM
( SELECT coupon_upc, coupon_id, division
FROM table2 WHERE schedule_key = 'xxx'
GROUP BY coupon_upc, coupon_id, division
) AS map
JOIN view1 a
ON a.coupon_id = map.coupon_id
AND a.division = map.division
WHERE
a.campaign_code = 'xxx'
GROUP BY
map.coupon_upc
在
JOIN
、WHERE
和GROUP BY
子句中使用的字段上是否有索引?提供查询和表/视图DDL语句会更容易帮助您。如果可以使用MVView而不是视图并在其上创建索引,则无权这样做!!如果没有table2
(尤其是view1
)定义语句,即使不是不可能,也很难提供帮助。
SELECT
map.coupon_upc
, COUNT(CASE WHEN a.loyalty_cell = 'A' THEN 1 ELSE NULL END) AS loyalty_a
, COUNT(CASE WHEN a.loyalty_cell = 'B' THEN 1 ELSE NULL END) AS loyalty_b
, COUNT(CASE WHEN a.loyalty_cell = 'C1' THEN 1 ELSE NULL END) AS loyalty_c
, COUNT(CASE WHEN a.loyalty_cell = 'X' THEN 1 ELSE NULL END) AS loyalty_x
FROM
( SELECT coupon_upc, coupon_id, division
FROM table2 WHERE schedule_key = 'xxx'
GROUP BY coupon_upc, coupon_id, division
) AS map
JOIN view1 a
ON a.coupon_id = map.coupon_id
AND a.division = map.division
WHERE
a.campaign_code = 'xxx'
GROUP BY
map.coupon_upc