簡體   English   中英

如何提高使用sqlplus的Perl腳本的效率

[英]How to increase efficiency of perl script which uses sqlplus

我有這個perl腳本,它從sqlplus數據庫中獲取數據...每當特定序列號的state值發生變化時,該數據庫都會添加一個新條目。 現在,我們需要在每次狀態更改時選擇條目,並准備一個具有舊狀態,新狀態和其他字段的csv文件。 db表示例。

SERIALNUMBER         STATE                AT                        OPERATORID    SUBSCRIBERID    TRANSACTIONID
51223344558899       Available            20081008T10:15:47         vsuser
51223344558857       Available            20081008T10:15:49         vsowner
51223344558899       Used                 20081008T10:20:25         vsuser
51223344558860       Stolen               20081008T10:15:49         vsanyone
51223344558857       Damaged              20081008T10:50:49         vsowner
51223344558899       Damaged              20081008T10:50:25         vsuser
51343253335355       Available            20081008T11:15:47         vsindian

我的腳本:

#! /usr/bin/perl

#use warnings;
use strict;


#my $circle =
#my $schema =
my $basePath = "/scripts/Voucher-State-Change";

#my ($sec, $min, $hr, $day, $month, $years) = localtime(time);
#$years_+=1900;$mont_+=1;
#my $timestamp=sprintf("%d%02d%02d",$years,$mont,$moday);


sub getDate {
    my $daysago=shift;
    $daysago=0 unless ($daysago);
    #my @months=qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time-(86400*$daysago));
    # YYYYMMDD, e.g. 20060126
    return sprintf("%d%02d%02d",$year+1900,$mon+1,$mday);
    }

my $filedate=getDate(1);
#my $startdate="${filedate}T__:__:__";
my $startdate="20081008T__:__:__";
print "$startdate\n";


##### Generating output file---
my $outputFile = "${basePath}/VoucherStateChangeReport.$filedate.csv";
open (WFH, ">", "$outputFile") or die "Can't open output file $outputFile for writing: $!\n";
print WFH "VoucherSerialNumber,Date,Time,OldState,NewState,UserId\n";



##### Generating log file---
my $logfile = "${basePath}/VoucherStateChange.$filedate.log";
open (STDOUT, ">>", "$logfile") or die "Can't open logfile $logfile for writing: $!\n";
open (STDERR, ">>", "$logfile") or die "Can't open logfile $logfile for writing: $!\n";
print "$logfile\n";

##### Now login to sqlplus-----
my $SQLPLUS='/opt/oracle/product/11g/db_1/bin/sqlplus -S system/coolman7@vsdb';
`$SQLPLUS \@${basePath}/VoucherQuery1.sql $startdate> ${basePath}/QueryResult1.txt`;


open (FH1, "${basePath}/QueryResult1.txt");

while (my $serial = <FH1>) {
     chomp ($serial);
     my $count = `$SQLPLUS \@${basePath}/VoucherQuery2.sql $serial $startdate`;
     chomp ($count);
     $count =~ s/\s+//g;
     #print "$count\n";
     next if $count == 1;

    `$SQLPLUS \@${basePath}/VoucherQuery3.sql $serial $startdate> ${basePath}/QueryResult3.txt`;

#  print "select * from sample where SERIALNUMBER = $serial----\n";
     open (FH3, "${basePath}/QueryResult3.txt");


     my ($serial_number, $state, $at, $operator_id);
     my $count1 = 0;
     my $old_state;
     while (my $data = <FH3>) {
            chomp ($data);
                    #print $data."\n";
           my @data = split (/\s+/, $data);
           my ($serial_number, $state, $at, $operator_id) = @data[0..3];
           #my $serial_number = $data[0];
           #my $state = $data[1];
           #my $at = $data[2];
           #my $operator_id = $data[3];


           $count1++;
           if ($count1 == 1) {
              $old_state = $data[1];
              next;
              }

           my ($date, $time) = split (/T/, $at);
           $date =~ s/(\d{4})(\d{2})(\d{2})/$1-$2-$3/;

           print WFH "$serial_number,$date,$time,$old_state,$state,$operator_id\n";
           $old_state = $data[1];
           }
       }
close(WFH);

在VoucherQuery1.sql中查詢:

select distinct SERIALNUMBER from sample where AT like '&1';

在VoucherQuery2.sql中查詢:

select count(*) from sample where SERIALNUMBER = '&1' and AT like '&2';

在VoucherQuery2.sql中查詢:

select * from sample where SERIALNUMBER = '&1' and AT like '&2';

和我的示例輸出:

VoucherSerialNumber,Date,Time,OldState,NewState,UserId
51223344558857,2008-10-08,10:50:49,Available,Damaged,vsowner
51223344558899,2008-10-08,10:20:25,Available,Used,vsuser
51223344558899,2008-10-08,10:50:25,Used,Damaged,vsuser

腳本運行正常。 但是問題在於實際的db表在特定的一天中有數百萬條記錄...因此會引發性能問題...請您告知我們如何在時間和負載方面提高此腳本的效率。 唯一的限制是我不能為此使用DBI模塊...另外,如果sql查詢中有任何錯誤,則QueryResult?.txt文件中將出現錯誤msg。 我想處理並在我的日志文件中收到這些錯誤。 如何做到這一點? 謝謝

我認為您需要調整查詢。 一個良好的起點是使用EXPLAIN PLAN(如果它是Oracle數據庫)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM