在ORACLE中如何优化SQL语句运行大约4秒?我想查询并使用更少的时间

How to optimize this SQL statement that run about 4 seconds in ORACLE?I want to query and use less time

我项目中的以下 sql 运行大约 4 seconds.TB_Order 进行了完整的 table 扫描。 table数据量TB_Order.The的state字段上有个索引是2000万,E和P的数据量小于50.ThisSQL即可optimized.and我用过UNION ALL,可以吗?你们有更好的sql吗?

--The first version
SELECT T.ORDER_ID, T.PRIORITY, T.SUB_TASK
FROM TB_ORDER T
WHERE (T.STATE = 'E' OR (T.STATE = 'P' AND SYSDATE > T.EFFECTIVE_DATE))
AND (T.PRIORITY <= 100 OR T.PRIORITY IS NULL)
AND ROWNUM <= :1

--The second version
SELECT * FROM (
SELECT T.ORDER_ID, T.PRIORITY, T.SUB_TASK
FROM TB_ORDER T
WHERE (T.STATE = 'E')
AND (T.PRIORITY <= 100 OR T.PRIORITY IS NULL)
UINON ALL 
SELECT T.ORDER_ID, T.PRIORITY, T.SUB_TASK
FROM TB_ORDER T
WHERE (T.STATE = 'P' AND SYSDATE > T.EFFECTIVE_DATE)
AND (T.PRIORITY <= 100 OR T.PRIORITY IS NULL)
)
where ROWNUM <= :1

不是最佳方法,消除了 OR 并强制执行 INDEX 扫描,尝试在没有 HINT 的情况下解释计划以查看是否使用了 TB_ORDER.STATE 上的索引。仅在未使用索引时添加提示。还推荐 运行 统计 TB_ORDER table.

SELECT * FROM
(SELECT /*+ INDEX(T STATE_NDX) */ T.ORDER_ID, T.PRIORITY, T.SUB_TASK
FROM TB_ORDER T
WHERE T.STATE = 'E'                        
AND DECODE(T.PRIORITY,null,0,T.PRIORITY) <= 100
AND ROWNUM <= :1
UNION ALL
SELECT /*+ INDEX(T STATE_NDX) */ T.ORDER_ID, T.PRIORITY, T.SUB_TASK
FROM TB_ORDER T
WHERE T.STATE = 'P' 
AND SYSDATE > T.EFFECTIVE_DATE
AND DECODE(T.PRIORITY,null,0,T.PRIORITY) <= 100
AND ROWNUM <= :1)

您可以使用 IN 替换为 UNION.The sql 将只查询一次 table。

  SELECT T.ORDER_ID, T.PRIORITY, T.SUB_TASK
   FROM TB_ORDER T
  WHERE T.STATE IN ('E', 'P')
  AND (CASE
     WHEN (T.STATE = 'P' AND SYSDATE > T.EFFECTIVE_DATE) THEN
      1
     WHEN T.STATE = 'E' THEN
      1
     ELSE
      0
   END) = 1
 AND (T.PRIORITY <= 100 OR T.PRIORITY IS NULL)
 AND ROWNUM <= :1