oracle在大型数据集中的sql性能

时间:2017-08-19 09:27:12

标签: sql oracle performance spring-data large-data

我有这样的查询。

我使用Jpa并且只检索前50个结果,但是我的桌子上有200万条记录需要很长时间。

如何提高效果?

SELECT * FROM TRANSACTION 
WHERE
   (trunc(REQUEST_TIME,'MI') between to_date('1390/01/01 01:01','YYYY/MM/DD HH24:MI','nls_calendar=persian') 
                                 and to_date('1396/11/01 01:01','YYYY/MM/DD HH24:MI','nls_calendar=persian'))
and  CUSTOMER like '%123%'
and  (case when (ERROR_CODE is not null and ERROR_CODE <> 200) then -1 
           when (ERROR_CODE is not null and ERROR_CODE =200) then 200 
       else 0 end =0)
and (URL = 'url1')
and ( SOURCE like '%123%')
and ( ERROR_CODE=200) 
and ( REQUEST_ID like '%1234%')

2 个答案:

答案 0 :(得分:0)

从这里删除datetime.datetime(2014, 7, 19, 0, 0)函数,它是无所事事但是阻止RDBMS在列TRUNC上使用索引(如果有的话):

REQUEST_TIME

从此处删除 (trunc(REQUEST_TIME,'MI') between ....... 条件,如果ERROR_CODE is not nullERROR_CODE <> 200,则它必须始终为NOT NULL:

ERROR_CODE =200

如果您简化上述条件,您将获得:

case when (ERROR_CODE is not null  and ERROR_CODE <> 200)
then -1 when (ERROR_CODE is not null and ERROR_CODE =200)
then 200 else 0 end =0)

如果你检查上面的简化条件,很明显它只检查“else 0”部分,所以它可以进一步简化为:

case when ERROR_CODE <> 200 then -1 
     when ERROR_CODE =200 then 200 
     else 0 
end =0

但由于您的查询ERROR_CODE IS NULL 中还有另一个条件,因此第一个条件会排除另一个条件and ( ERROR_CODE=200),所以我认为您没有向我们展示问题中的真实查询。我只是删除这个条件,因为它很可能是一个逻辑错误。

经过上述简化后,您将获得:

and ( ERROR_CODE=200)

现在确保在SELECT * FROM TRANSACTION WHERE REQUEST_TIME between to_date('1390/01/01 01:01','YYYY/MM/DD HH24:MI','nls_calendar=persian') and to_date('1396/11/01 01:01','YYYY/MM/DD HH24:MI','nls_calendar=persian') and CUSTOMER like '%123%' and (URL = 'url1') and ( SOURCE like '%123%') and ( ERROR_CODE=200) and( REQUEST_ID like '%1234%') 上创建了一个索引,如果没有,则创建它并验证查询的性能。

答案 1 :(得分:0)

前提是这不是ad-hoc(很少使用)类型的查询 将trunc(REQUEST_TIME,'MI')上的功能索引定义为列。