如何增强sql查询的性能?

时间:2015-04-05 05:29:19

标签: 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("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';

但是数据库表包含数百万条记录,即使是简单的select count(*)查询也无法生成输出。现在问题是在创建数据库时没有定义约束。

我有编写脚本的经验,但就性能而言,我是SQL查询的新手。

我想问一下

  • 如果我在表中定义主键约束,会有多大差异? (它是第三方服务器,因此在进行任何更改之前我必须确定。)

  • 索引是否会改善效果?他们怎么能帮助这个特定的查询呢?

  • 我应该将此查询分解为更简单的查询吗?

这是表格描述

SQL> DESC VOUCHER;
Name                        Null?                 Type
--------------------------  -------- -------------------------------
SERIALNUMBER                          VARCHAR2(20)
STATE                                 VARCHAR2(4000)
AT                                    VARCHAR2(4000)
OPERATORID                            VARCHAR2(4000)
SUBSCRIBERID                          VARCHAR2(20)
TRANSACTIONID                         VARCHAR2(20)

还有一件事。我必须处理SQL * Plus,因为Solaris问题,我不能将DBIDBD::Oracle模块一起使用。我想自己解决这个问题,但需要你对这些性能问题的建议,因为我不能在它们上使用命中和遗漏方法。

1 个答案:

答案 0 :(得分:0)

我在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相关的所有记录,只要这些记录中至少有一个at匹配的&1列。