Oracle 如何提高sql查询的性能?
下面是我的脚本的主要部分,它通过SQL*Plus与Oracle数据库交互Oracle 如何提高sql查询的性能?,oracle,performance,perl,shell,sqlplus,Oracle,Performance,Perl,Shell,Sqlplus,下面是我的脚本的主要部分,它通过SQL*Plus与Oracle数据库交互 #--------------- Now connecting to sqlplus `$SQLPLUS \@${basePath}/VoucherQuery.sql $startdate> ${basePath}/logs/QueryResult.$currentDate.log`; if ( $? == 0) { logger("Processi
#--------------- Now connecting to sqlplus
`$SQLPLUS \@${basePath}/VoucherQuery.sql $startdate> ${basePath}/logs/QueryResult.$currentDate.log`;
if ( $? == 0) {
logger("Processing with the sqlplus is completed. For more details check ${basePath}/logs/QueryResult.$currentDate.log ", 0); }
else {
logger("Not able to fetch data from sqlplus. Please check", 1); exit;}
#print "select * from sample where SERIALNUMBER = $serial\n";
open (FH, "${basePath}/logs/QueryResult.$currentDate.log") or die "Can't open query ${basePath}/logs/QueryResult.$currentDate.log file: $!\n";
my ($serial_number, $state, $at, $operator_id, $old_state);
while (my $data = <FH>) {
chomp ($data);
#print $data."\n";
my @data = split (/\s+/, $data);
my ($serial_number, $state, $at, $operator_id, $old_state) = @data[0..4];
my ($date, $time) = split (/T/, $at);
$date =~ s/(\d{4})(\d{2})(\d{2})/$3-$month{$2}-$1/;
$date =~ s/(.*)(\d{2})(\d{2})/$1$3/;
print WFH "$circle,$date,$time,$operator_id,$serial_number,$old_state,$state\n";
}
close(FH);
close(WFH);
-------------------------------------------------------------
>cat VoucherQuery.sql
SELECT * FROM (SELECT serialnumber, state, at, operatorid, lag(state) OVER ( PARTITION BY serialnumber ORDER BY at) AS previous FROM VOUCHER) WHERE at LIKE '&1';
还有一件事。我必须处理SQL*Plus,但由于Solaris问题,我不能将
DBI
与DBD::Oracle
模块一起使用。我想自己解决这个问题,但需要您对这些性能问题的建议,因为我不能对它们使用命中和未命中的方法。与其他数据库相比,我在Oracle方面的经验要少得多,因此这可能是不正确的。但是如果它能工作,它肯定会比您现有的SQL更快,因为它会在添加previous
列之前限制它首先处理的数据
SELECT
serialnumber,
state,
at,
operatorid,
LAG(state) OVER (PARTITION BY serialnumber ORDER BY at) AS previous
FROM
voucher
WHERE
serialnumber in (SELECT DISTINCT serialnumber FROM voucher WHERE at LIKE '&1')
请注意,它不会产生与您自己的查询完全相同的结果,因为它将包括与给定的
serialnumber
相关的所有记录,只要这些记录中至少有一条在处有一列与&1
匹配的您的cat
输出看起来像是VoucherQuery.sql
而不是QueryResult.$currentDate.log
?从您的查询来看,serialnumber
似乎不是唯一的,因此,除非Oracle允许非唯一主键,否则我认为如果您将serialnumber
声明为主键,它将崩溃。阻止您使用DBI的“Solaris问题”是什么?对于数以百万计的记录,我认为使用该SQL永远不会有合理的反应时间,因为它首先使用每个序列号的state列的前一个值获取整个数据库。一旦这样做了,它就会通过at
过滤结果,并可能会丢弃它刚刚完成的大部分工作。首先,我将执行从凭证中选择不同的序列号,其中类似于“&1”
,然后将每条记录与其以前的状态关联起来。serialnumber
上的索引(不是PK)会很好。@Borodin感谢您的回复。。你是对的。。我已经改正了我的错误。。但主值不能是非唯一值。。。这里主键和状态的组合可以是PK。。这会有什么影响吗?这是关于DBI的解释。“我不介意执行的时间太长。”。。但问题是。。它只是一直在等待,甚至在一个小时内都没有响应。我会尝试“独特”选项并让你知道。。。
SELECT
serialnumber,
state,
at,
operatorid,
LAG(state) OVER (PARTITION BY serialnumber ORDER BY at) AS previous
FROM
voucher
WHERE
serialnumber in (SELECT DISTINCT serialnumber FROM voucher WHERE at LIKE '&1')