我有一个问题:
假设一条装配线,其中一辆自行车经过一些测试,然后设备将有关测试的信息发送到 我们的数据库(在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;
感谢您的回答!!
答案 0 :(得分:0)
我正在努力了解您提供的英文描述中的业务需求。措辞表明此程序旨在每辆自行车,但我没有看到提供任何明显的bike_id参数,相反,您似乎返回全部在给定日期之间测试自行车。这是目的吗?如果它设计为每辆自行车运行,那么确保自行车ID传递并尽早使用:)
您的数据类型存在一些混淆。您将result_test中的testtime(可能是DATE或TIMESTAMP列)转换为p_bikelist子查询中的字符串,然后将其与tv子查询中的原始值进行比较。您还可以使用(推测类型参数)p_startdate和p_enddate来过滤结果。我强烈怀疑p_bikelist中的转换是不必要的,并且可能是索引避免的原因。
最后,我没有得到add_months逻辑。无论如何,要及时延长窗口以在窗口内进行完成的测试,但是在开始日期之前的2个月开始,但是如上所述,由于条件的原因,您将排除先前的启动在tv.testtime上。最有可能的是,你最好先使用类似
的代码来捏造存储过程中的startdatel_assumedstart := add_months(p_startdate, -2);
然后在查询本身中使用l_assumedstart。