1

如何在 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)
    )
) 
4

6 回答 6

2

优化器负责优化您的查询;放松,让它做自己的事情。

您尝试的任何显式缓存都将涉及临时表(您已排除)之类的内容,因此您只能通过使用 CTE(公用表表达式,又名 WITH 子句)来命名公用查询,从而使公用查询更加明确子查询。但是优化器可能会以同样的方式处理事情。

您可以将 IN 子句替换为 JOIN;那可能会更快。同样,优化器可能会这样做。但是,这不是缓存操作。这是一个标准的查询重写。

于 2012-06-25T15:59:25.790 回答
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;
于 2012-06-25T16:01:23.033 回答
0

选择order_id, mod_id from orders o inner join orderline ol on o.order_id = ol.order_line_id

于 2012-06-25T16:01:47.017 回答
0

您也许可以删除此行:

 WHERE order_id IN (Select order_id FROM Orders)

如果您的数据库具有完整性,则不允许出现孤儿,并且此行不会过滤任何内容。

于 2012-06-25T16:02:45.097 回答
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;
于 2012-06-25T16:05:02.730 回答
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)
)
于 2012-06-25T16:22:56.847 回答