我正在使用Select查询中的几个and
语句从oracle表中选择数据。另外,我正在使用Like语句。问题是当我使用大表时,执行查询会花费太多时间。我该如何更改下面查询的某些部分。
SELECT t.co_filial as fil_code, t.emp_birth as emp_code, to_char(t.curr_day, 'YYYY-MM-DD') as operation_date,
TRUNC(t.Sum_Pay/100) As summa
FROM operation_history t
WHERE Substr(t.Co_Acc, 8) LIKE '12294%' And Substr(t.Co_Acc, -3) > 599 And Substr(t.Co_Acc, -3) != 683 And Substr(t.Co_Acc, -3) < 696
AND t.state_id = 41
And t.curr_day >= to_date('12.08.2019', 'DD.MM.YYYY')
And t.curr_day < to_date('13.08.2019', 'DD.MM.YYYY')
答案 0 :(得分:3)
一个明显的改进是:Substr
的用于提取最后3个字符的字符串可以使用一次,而不是三次,并且可以在子查询中使用,如下所示。
SELECT fil_code,
emp_code,
operation_date,
summa
From
(SELECT t.co_filial as fil_code,
t.emp_birth as emp_code,
to_char(t.curr_day, 'YYYY-MM-DD') as operation_date,
TRUNC(t.Sum_Pay/100) As summa,
Substr(t.Co_Acc, -3) AS SUBSTR_3 -- ADDED THIS
FROM operation_history t
WHERE Substr(t.Co_Acc, 8, 5) = '12294' -- used direct equals operator
--And Substr(t.Co_Acc, -3) > 599
--And Substr(t.Co_Acc, -3) != 683
--And Substr(t.Co_Acc, -3) < 696
AND t.state_id = 41
And t.curr_day >= to_date('12.08.2019', 'DD.MM.YYYY')
And t.curr_day < to_date('13.08.2019', 'DD.MM.YYYY'))
-- added following where clause
WHERE SUBSTR_3 BETWEEN 600 AND 695
AND SUBSTR_3 != 683
我使用了between
,其中包括上限值和下限值,因此要从相应的限制中加减1。
干杯!
答案 1 :(得分:0)
对于此查询(我已经进行了一些清理):
SELECT t.co_filial as fil_code, t.emp_birth as emp_code, to_char(t.curr_day, 'YYYY-MM-DD') as operation_date,
TRUNC(t.Sum_Pay/100) As summa
FROM operation_history t
WHERE Substr(t.Co_Acc, 8) LIKE '45294%' And Substr(t.Co_Acc, -3) > 599 And
Substr(t.Co_Acc, -3) <> 683 And
Substr(t.Co_Acc, -3) < 696 AND
t.state_id = 41 And
t.curr_day >= date '2019-08-12' and
t.curr_day < date '2019-08-13';
要使其运行更快,您想在WHERE
子句上使用索引。那可能是唯一可以带来明显改善的东西。
我建议在operation_history(state_id, curr_date, Substr(t.Co_Acc, 8))
上建立索引。
因为您只在结果中寻找一天,所以您还可以做另一件事:
SELECT t.co_filial as fil_code, t.emp_birth as emp_code, to_char(t.curr_day, 'YYYY-MM-DD') as operation_date,
TRUNC(t.Sum_Pay/100) As summa
FROM operation_history t
WHERE Substr(t.Co_Acc, 8) LIKE '45294%' and
Substr(t.Co_Acc, -3) > 599 and
Substr(t.Co_Acc, -3) <> 683 and
Substr(t.Co_Acc, -3) < 696 and
t.state_id = 41 and
trunc(t.curr_day) = date '2019-08-12';
然后,所需的索引位于operation_history(state_id, trunc(curr_date), Substr(t.Co_Acc, 8))
上。
答案 2 :(得分:0)
一些建议:
1)无需动态计算operation_date substr_3和summa字段,而是创建3个生成的(计算的)列,每个表达式一个。这些将在数据库中预先计算,您只需要选择计算列即可。快多了。列应该是持久性的(不是虚拟的)
https://oracle-base.com/articles/11g/virtual-columns-11gr1
2)检查是否可以对这些substr表达式进行相同操作
3)为您在2)中创建的计算列创建索引(如果有的话)
4)为stateid和curr_day创建索引
致谢