如何修复我的查询,以便过滤器不会减慢它的速度?

时间:2015-12-21 21:31:23

标签: sql oracle optimization

这个问题很简单但我想的答案不是......

我有一个快速运行的查询 - 在一秒钟之内。但是,如果我将许多值传递给过滤条件,那么它会减慢很多。

例如,它运行速度很快:

SELECT * FROM MYTABLE
WHERE DATE_COLUMN > TRUNC(SYSDATE-30)

但如果我进行以下添加,那么相同的代码运行速度非常慢:

SELECT * FROM MYTABLE
WHERE DATE_COLUMN > TRUNC(SYSDATE-30)
AND MYVALUE IN ('A', 'B', 'C', 'D', 'E')

有没有什么可以用SQL来修改它。我的目标是让查询快速运行,最好是在一秒钟之内。

我尝试过GROUP BY,但它并没有什么区别。

我排除了所有可能性,问题出在IN (multiple values)部分。

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

评论太长了。

您如何衡量第一个查询的速度?一种可能性是您正在测量返回的 first 值的速度而不是最后一个值 - 并且Oracle发现很容易返回满足第一个条件的值。检查此问题的一种方法是使用order by,因为这需要获取所有行(然后执行更多工作):

SELECT *
FROM MYTABLE
WHERE DATE_COLUMN > TRUNC(SYSDATE-30)
ORDER BY othercol;

ORDER BY通常会处理所有数据。)

假设你没有犯这个错误,另一个潜在的问题是使用索引。 Oracle通常对此非常满意。并且,您可以使用执行计划来查看执行计划是否相同。例如,您可能在date_column上有一个索引,在myvalue上有一个索引。 Oracle可能会选择错误的索引。

如果是这种情况,您可以在(myvalue, datecol)上创建索引并尝试运行此查询:

SELECT *
FROM MYTABLE
WHERE DATE_COLUMN > TRUNC(SYSDATE-30) AND
      MYVALUE = 'A';

如果运行速度很快,请尝试查询索引。如果这不起作用,请使用UNION ALL

SELECT *
FROM MYTABLE
WHERE DATE_COLUMN > TRUNC(SYSDATE-30) AND MYVALUE = 'A'
UNION ALL
SELECT *
FROM MYTABLE
WHERE DATE_COLUMN > TRUNC(SYSDATE-30) AND MYVALUE = 'B'
UNION ALL
. . .

答案 1 :(得分:0)

1)找出用于第一个查询的实际索引(可以查看“解释计划”),然后在第二个SQL中添加一个提示/ * +索引(MYTABLE MYINDEX)* /以确保

也使用相同的索引

2)使用下面的SQL强制首先处理子查询

SELECT * FROM (
  SELECT /*+no_merge*/ ROWNUM row_num, t.* FROM MYTABLE t
  WHERE DATE_COLUMN > TRUNC(SYSDATE-30)
) WHERE MYVALUE IN ('A', 'B', 'C', 'D', 'E')

答案 2 :(得分:0)

我觉得可以通过使用解释计划查看查询是否运行得更快,以查看内部发生的情况。 我建议:

  • 检查两个查询的解释计划,看看执行方式有何不同。
  • myvalue列上可能没有索引导致查询性能受到影响。
  • 无论如何,在看到两个查询的实际解释计划后,可以说更多。

希望这有助于缩小问题范围。