下面是我的脚本的主要部分,它通过SQL * Plus与Oracle数据库进行交互。如何提高sql查询的性能?
#--------------- 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问题,我无法使用DBI
和DBD::Oracle
模块。我想自己解决这个问题,但需要你就这些性能问题提出建议,因为我不能在它们上使用命中和错过方法。
您的'cat'输出看起来像是'VoucherQuery.sql'的内容而不是'QueryResult。$ currentDate.log'的内容?在你的查询中,它看起来像'serialnumber'不是唯一的,所以除非Oracle允许非唯一主键,否则如果你声明'serialnumber'是主键,它会中断 – Borodin 2015-04-05 06:57:21
什么是*“Solaris问题”*阻止您使用DBI?有了数百万条记录,我认为你永远不会使用该SQL进行合理的反应时间,因为它始于以每个序列号的状态列的前一个值提取整个数据库。一旦它完成了,它会通过'at'来过滤结果,并且可能会抛弃刚刚完成的大部分工作。我会先从'SELECT DISTINCT serialnumber FROM voucher WHERE'LIKE'&1''开始,然后*然后*将每条记录与之前的状态关联起来。 'serialnumber'上的一个*索引*(不是PK)会很好。 – Borodin 2015-04-05 07:10:31
@Borodin谢谢你的回应..你是对的..我纠正了我的错误..但是主要不是非唯一的价值......在这里主键和国家的组合可能是PK ..它会产生什么影响? 这里是对DBI的解释“http://www.perlmonks.org/?node=Not+able+to+install+DBD%3A%3AOracle+on+sun+solaris。“我不会介意是否需要太多时间才能执行......但问题是......它只是等待并且即使在一小时内也没有响应......我会尝试”DISTINCT“选项并让你知道...... – Ankur 2015-04-05 07:34:32