如何优化以下SQL(复杂查询的简化视图)。理想情况下,我应该能够缓存第一个SQL结果(订单ID)并在第二个查询中对OrderLine表进行某种投影。
任何指针都会有所帮助。
限制 - 我无法创建临时表,游标或过程/函数。我正在连接到Oracle 10g。
SELECT 'Object_id', id, mod_id FROM
(
(Select 'Order_id', order_id, mod_id FROM Orders)
UNION
(select 'Order_line_id', order_line_id, mod_id FROM OrderLine
WHERE order_id IN (Select order_id FROM Orders)
)
)
答案 0 :(得分:2)
优化器负责优化您的查询;放松,让它做它的东西。
您尝试的任何显式缓存都会涉及临时表(您已排除)之类的内容,因此您可以通过使用CTE(公用表表达式,也就是WITH子句)来使公共查询更明确。命名公共子查询。但无论如何,优化器都可能以相同的方式处理事情。
您可以用JOIN替换IN子句;这可能会更快。同样,优化器可能会这样做。但是,这不是缓存操作;它是标准的查询重写。
答案 1 :(得分:1)
您可以根据以下示例设计查询:
WITH CTE AS
(
Select 'Order_id' Descr, order_id, mod_id FROM Orders
)
, CTE2 AS
(
SELECT * FROM CTE
UNION
SELECT 'Order_line_id' Descr, order_line_id, mod_id FROM OrderLine ol
WHERE EXISTS (Select order_id FROM CTE WHERE order_id = ol.order_id)
)
SELECT * FROM CTE2;
答案 2 :(得分:0)
选择order_id,mod_id 来自订单o 内连接订单线ol 在o.order_id = ol.order_line_id
答案 3 :(得分:0)
您可以删除此行:
WHERE order_id IN (Select order_id FROM Orders)
如果您的数据库具有完整性,则不允许孤立,此行不会过滤任何内容。
答案 4 :(得分:0)
with myOrders as (
select order_id,
mod_id
from Orders
)
select 'order_id' obj_type,
order_id,
mod_id
from myOrders
union all
select 'order_line_id' obj_type,
order_line_id,
mod_id
from OrderLine
join myOrders
on OrderLine.order_id = myOrders.order_id;
答案 5 :(得分:0)
您可以尝试以下内容......
SELECT DISTINCT 'Object_id', id, mod_id
FROM
(
SELECT
CASE
WHEN CROSSNUM = 1 THEN 'Order_ID'
ELSE 'Order_Line_ID'
END AS Object_ID,
CASE
WHEN CROSSNUM = 1 THEN order_id
ELSE order_line_id
END AS id,
CASE
WHEN CROSSNUM = 1 THEN Orders.mod_id
ELSE OrderLine.mod_id
END AS mod_id
FROM
(Select 'Order_id', order_id, mod_id FROM Orders) Orders
LEFT JOIN (select 'Order_line_id', order_line_id, mod_id FROM OrderLine) OrderLine
ON Orders.Order_id = OrderLine.Order_Id
CROSS JOIN
(
SELECT 1 AS CROSSNUM FROM DUAL
UNION ALL
SELECT 2 AS CROSSNUM FROM DUAL
) X
WHERE
NOT (CROSSNUM = 2 AND order_line_id IS NULL)
)