如何改进此存储过程?

时间:2017-10-27 14:25:22

标签: oracle stored-procedures

我有一个问题:

假设一条装配线,其中一辆自行车经过一些测试,然后设备将有关测试的信息发送到 我们的数据库(在oracle中)。我创建了这个存储过程;它适用于我想要的,这是:

它获得了自行车经历的第一次测试(每种测试类型)的列表。例如,如果一辆自行车有2个相同类型的测试,那么它只是 显示第一个,它仅在第一个测试介于用户指定的日期之间时显示。我也从2个月前看 因为自行车不能在装配线上花费超过2个月(我可能会高估),但如果用户搜索2天,我只是在那些日子之间查看,我可以在结果之外进行测试3天前或者4天骑自行车,如果他们在几小时之间搜索就会变得最糟糕。 正如我之前所说,sp工作正常,但我想知道是否有一种方法可以优化它。 还要考虑到今年年底该表有大约7百万条记录,因此我无法查询全年,因为它可能会变得难看。

这是存储过程的主要部分:

SELECT pid                                AS "bike_id",             
         TYPE                               AS "type",
         stationnr                          AS "stationnr",
         testtime                           AS "testtime",
         rel2.releasenr                     AS "releasenr",
         placedesc                          AS description,
         tv.recordtime                      AS "recordtime",
         To_char(tv.testtime, 'YYYY.MM.DD') AS "dategroup",
         testcounts                         AS "testcounts",
         tv.result                          AS "result",
         progressive                        AS "PROGRESIVO"
  FROM   (SELECT l_bike_id                                        AS pid,
                 l_testcounts                                 AS testcounts,
                 To_char(l_testtime, 'yyyy-MM-dd hh24:mi:ss') AS testtimes,
                 testtime,
                 pl.code                                      AS place,                     
                 t2.recordtime,
                 t2.releaseid,
                 t2.testresid,                     
                 t2.stationnr,
                 t2.result,                                          
                 v.TYPE,
                 v.progressive,
                 v.prs,
                 pl.description                               AS placeDesc
          FROM   (SELECT v.bike_id             AS l_bike_id,
                         v.TYPE            AS l_type,
                         Min(t.testtime)   AS l_testtime,
                         Count(t.testtime) AS l_testcounts
                  FROM   result_test t
                         inner join bikes v
                                 ON v.bike_id = t.pid
                         inner join result_release rel
                                 ON t.releaseid = rel.releaseid
                         inner join resultconfig.places p
                                 ON p.place = t.place
                  WHERE  t.testtime >= Add_months(Trunc(p_startdate), -2)
                  GROUP  BY v.bike_id,
                            v.TYPE,
                            p.code)p_bikelist
                 inner join result_test t2
                         ON p_bikelist.l_bike_id = t2.pid
                            AND p_bikelist.l_testtime = t2.testtime
                 inner join resultconfig.places pl
                         ON pl.place = t2.place
                 inner join bikes v
                         ON v.bike_id = t2.pid
                 inner join result_release rel2
                         ON t2.releaseid = rel2.releaseid
          ORDER  BY t2.pid)tv
         inner join result_release rel2
                 ON tv.releaseid = rel2.releaseid
  WHERE   tv.testtime BETWEEN p_startdate AND p_enddate             
  ORDER  BY testtime;

感谢您的回答!!

1 个答案:

答案 0 :(得分:0)

我正在努力了解您提供的英文描述中的业务需求。措辞表明此程序旨在每辆自行车,但我没有看到提供任何明显的bike_id参数,相反,您似乎返回全部在给定日期之间测试自行车。这是目的吗?如果它设计为每辆自行车运行,那么确保自行车ID传递并尽早使用:)

您的数据类型存在一些混淆。您将result_test中的testtime(可能是DATE或TIMESTAMP列)转换为p_bikelist子查询中的字符串,然后将其与tv子查询中的原始值进行比较。您还可以使用(推测类型参数)p_startdate和p_enddate来过滤结果。我强烈怀疑p_bikelist中的转换是不必要的,并且可能是索引避免的原因。

最后,我没有得到add_months逻辑。无论如何,要及时延长窗口以在窗口内进行完成的测试,但是在开始日期之前的2个月开始,但是如上所述,由于条件的原因,您将排除先前的启动在tv.testtime上。最有可能的是,你最好先使用类似

的代码来捏造存储过程中的startdate
l_assumedstart := add_months(p_startdate, -2);    

然后在查询本身中使用l_assumedstart。