[英]How to optimize this SQL statement that run about 4 seconds in ORACLE?I want to query and use less time
The following sql in my project runs about 4 seconds.TB_Order has a full table scan.我项目中的以下 sql 运行大约 4 秒。TB_Order 进行了全表扫描。 There is an index on the state field of TB_Order.The data volume of the table is 20 million, and the data volume of E and P is less than 50.This SQL can be optimized.and I have use UNION ALL,is it right?Do you have a better sql?
TB_Order的state字段有索引。表的数据量是2000万,E和P的数据量小于50。这个SQL是可以优化的。而且我用过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
Not a best approach,eliminated OR and forced INDEX Scan,Try explain plan without HINT to see if index on TB_ORDER.STATE is utilized.不是最好的方法,消除 OR 并强制 INDEX 扫描,尝试在没有 HINT 的情况下解释计划以查看是否使用了 TB_ORDER.STATE 上的索引。 Add the hint only if index is not used.
只有在不使用索引时才添加提示。 Also recommend run statistics on TB_ORDER table.
还建议在 TB_ORDER 表上运行统计信息。
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)
You may use IN to replace with UNION.The sql will query the table only one time.您可以使用 IN 替换为 UNION。sql 将只查询一次表。
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.