create table speedtest (
id integer,
name varchar2(16),
aod date,
curr1 varchar2(6),
price1 number,
curr2 varchar2(6),
price2 number
);
####
#!/usr/local/bin/perl
use strict;
use warnings;
use feature qw/say/;
use Data::Dumper;
use Time::HiRes qw/gettimeofday tv_interval/;
use DBI;
#--------------------------------------------------------
sub rowcnt
{
my $dbh = shift;
my $rowcnt = $dbh->selectrow_array('select count(*) from speedtest');
return $rowcnt;
}
#--------------------------------------------------------
sub gencurr
{
my @set = 'A' .. 'F';
return join '' => map $set[rand @set], 1 .. 3;
}
#--------------------------------------------------------
sub genstr
{
my $len = shift;
return sprintf("%08X", rand(0x7fffffff));
}
#--------------------------------------------------------
sub gennum
{
return sprintf("%08d", rand(0x7fffffff));
}
#--------------------------------------------------------
sub gendate
{
# 0 1 2 3 4 5 6 7 8
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
localtime(rand(0xffffffff));
return sprintf("%04d-%02d-%02d", $year+1900, $mon+1, $mday);
}
#--------------------------------------------------------
sub genreal
{
return sprintf("%10.6f", rand(0xffffffff));
}
#--------------------------------------------------------
sub gendata
{
my $count = shift;
my $d;
for(my $i=0; $i<$count; ++$i) {
$d->{$i}->{id} = gennum();
$d->{$i}->{name} = genstr();
$d->{$i}->{aod} = gendate();
$d->{$i}->{curr1} = gencurr();
$d->{$i}->{price1} = genreal();
$d->{$i}->{name} = genstr();
$d->{$i}->{curr2} = gencurr();
$d->{$i}->{price2} = genreal();
}
return $d;
}
#--------------------------------------------------------
sub testins1
{
my $dbh = shift;
my $data = shift;
say 'positional bind_param and execute by row';
my $isql = q{
insert /*+ append */ into speedtest
(id, name, aod, curr1, price1, curr2, price2)
values
(?, ?, ?, ?, ?, ?, ?)
};
my $isth = $dbh->prepare($isql);
for my $i (sort keys %$data) {
$isth->bind_param(1, $data->{$i}->{id});
$isth->bind_param(2, $data->{$i}->{name});
$isth->bind_param(3, $data->{$i}->{aod});
$isth->bind_param(4, $data->{$i}->{curr1});
$isth->bind_param(5, $data->{$i}->{price1});
$isth->bind_param(6, $data->{$i}->{curr2});
$isth->bind_param(7, $data->{$i}->{price2});
$isth->execute;
}
$isth->finish;
$dbh->commit;
}
#--------------------------------------------------------
sub testins2
{
my $dbh = shift;
my $data = shift;
say 'positional execute and execute by row';
my $isql = q{
insert /*+ append */ into speedtest
(id, name, aod, curr1, price1, curr2, price2)
values
(?, ?, ?, ?, ?, ?, ?)
};
my $isth = $dbh->prepare($isql);
my @fields = qw/id name aod curr1 price1 curr2 price2/;
for my $i (sort keys %$data) {
$isth->execute(@{$data->{$i}}{@fields});
}
$isth->finish;
$dbh->commit;
}
#--------------------------------------------------------
sub testins3
{
my $dbh = shift;
my $data = shift;
say 'positional execute array';
my $isql = q{
insert /*+ append */ into speedtest
(id, name, aod, curr1, price1, curr2, price2)
values
(?, ?, ?, ?, ?, ?, ?)
};
my $isth = $dbh->prepare($isql);
my $id = [map { $data->{$_}->{id} } sort keys %$data];
my $name = [map { $data->{$_}->{name} } sort keys %$data];
my $aod = [map { $data->{$_}->{aod} } sort keys %$data];
my $curr1 = [map { $data->{$_}->{curr1} } sort keys %$data];
my $price1 = [map { $data->{$_}->{price1} } sort keys %$data];
my $curr2 = [map { $data->{$_}->{curr2} } sort keys %$data];
my $price2 = [map { $data->{$_}->{price2} } sort keys %$data];
my $t0 = [gettimeofday];
my $rv = $isth->execute_array({ ArrayTupleStatus => \my @tuple_status },
$id, $name, $aod, $curr1, $price1, $curr2, $price2);
my $elapsed = tv_interval($t0, [gettimeofday]);
say "\texecute_array takes $elapsed sec, $rv rows";
my @err = grep {$_ != -1} @tuple_status;
say "\terr: @err";
$isth->finish;
$dbh->commit;
}
#--------------------------------------------------------
sub testins4
{
my $dbh = shift;
my $data = shift;
say 'bind_param by name and execute by row';
my $isql = q{
insert /*+ append */ into speedtest
(id, name, aod, curr1, price1, curr2, price2)
values
(:id, :name, :aod, :curr1, :price1, :curr2, :price2)
};
my $isth = $dbh->prepare($isql);
for my $i (sort keys %$data) {
$isth->bind_param(':id', $data->{$i}->{id});
$isth->bind_param(':name', $data->{$i}->{name});
$isth->bind_param(':aod', $data->{$i}->{aod});
$isth->bind_param(':curr1', $data->{$i}->{curr1});
$isth->bind_param(':price1', $data->{$i}->{price1});
$isth->bind_param(':curr2', $data->{$i}->{curr2});
$isth->bind_param(':price2', $data->{$i}->{price2});
$isth->execute;
}
$isth->finish;
$dbh->commit;
}
#========================================================
$Data::Dumper::Sortkeys = 1;
my $dbname = '???';
my $user = '???';
my $passwd = '???';
my $count = $ARGV[0] // 1;
my $verbose = 0;
$| = 1;
my $dbh = DBI->connect("dbi:Oracle:$dbname", $user, $passwd,
{
AutoCommit => 0,
RaiseError => 1,
RowCacheSize => 10000,
ora_array_chunk_size => 100000,
#ora_check_sql => 0,
#ora_verbose => 0xff,
#ora_oci_success_warn => 1,
}
);
print 'DBI version: ', $DBI::VERSION, "\n";
print 'DBD version: ', $DBD::Oracle::VERSION, "\n";
$dbh->do("alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS'");
$dbh->do("alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS.FF'");
say "RowCacheSize: ", $dbh->{RowCacheSize};
my $data = gendata($count);
say Dumper($data) if $verbose;
my ($t0, $elapsed);
$dbh->do('truncate table speedtest') or die "SPEEDTEST truncate failed";
$t0 = [gettimeofday];
testins1($dbh, $data);
$elapsed = tv_interval($t0, [gettimeofday]);
say "1 Elapsed: $elapsed sec " . rowcnt($dbh) . " rows";
$dbh->do('truncate table speedtest') or die "SPEEDTEST truncate failed";
$t0 = [gettimeofday];
testins2($dbh, $data);
$elapsed = tv_interval($t0, [gettimeofday]);
say "2 Elapsed: $elapsed sec " . rowcnt($dbh) . " rows";
$dbh->do('truncate table speedtest') or die "SPEEDTEST truncate failed";
$t0 = [gettimeofday];
testins3($dbh, $data);
$elapsed = tv_interval($t0, [gettimeofday]);
say "3 Elapsed: $elapsed sec " . rowcnt($dbh) . " rows";
$dbh->do('truncate table speedtest') or die "SPEEDTEST truncate failed";
#$dbh->{ora_verbose} = 6;
#$dbh->{ora_oci_success_warn} = 1;
$t0 = [gettimeofday];
testins4($dbh, $data);
$elapsed = tv_interval($t0, [gettimeofday]);
say "4 Elapsed: $elapsed sec " . rowcnt($dbh) . " rows";
$dbh->disconnect;
exit 0;
__END__
##
##
//
// g++ -std=c++11 -Wall -g speedtest.cpp -I/usr/local/include
// -I ${ORACLE_HOME}/rdbms/public -L ${ORACLE_HOME}/lib -lclntsh
// -o speedtest && ./speedtest
//
#include
#include
#include
#include
#include
#include
#define OTL_ORA12C
#define OTL_STL
#define OTL_EXCEPTION_STM_TEXT_SIZE 32767
#define OTL_ORA_UTF8
#if 0
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define OTL_TRACE_LEVEL 0xff
#define OTL_TRACE_STREAM cerr
#define OTL_TRACE_LINE_PREFIX "MY OTL TRACE " __FILE__ ":" TOSTRING(__LINE__) " ==> "
#endif
using namespace std;
#include // include the OTL 4.0 header file
class data {
public:
data(size_t nrows = 1)
: c_numrows(nrows),
c_strlen(8)
{
genint(id);
genstr(name);
gendate(aod);
gencurr(curr1);
gendouble(price1);
gencurr(curr2);
gendouble(price2);
}
void print(void);
string pdate(struct tm);
size_t c_numrows;
vector id;
vector name;
vector aod;
vector curr1;
vector price1;
vector curr2;
vector price2;
private:
size_t c_strlen;
void gencurr(vector &);
void genstr(vector &);
void genint(vector &);
void gendouble(vector &);
void gendate(vector &);
};
void data::print(void)
{
cout << "Num of rows: " << c_numrows << '\n';
for(size_t n=0; n & cvec)
{
for(size_t n=0; n & vstr)
{
for(size_t n=0; n & vint)
{
for(size_t n=0; n & vdouble)
{
for(size_t n=0; n & vtm)
{
for(size_t n=0; n, :name, :aod, :curr1, :price1, :curr2, :price2)",
db // connect object
);
for(size_t i=0; i= 2 )? argv[1] : "") << endl;
//------------------------------------------------
data d(argc >= 2 ? atoi(argv[1]) : 1);
//d.print();
//------------------------------------------------
int i = argc >= 3 ? atoi(argv[2])-1 : 0;
cout << setw(8) << i+1 << " " <<
setw(10) << d.id[i] << " - " <<
d.name[i] << " - " <<
d.pdate(d.aod[i]) << " - " <<
d.curr1[i] << " - " <<
setw(10) << d.price1[i] << " - " <<
d.curr2[i] << " - " <<
setw(10) << d.price2[i] << endl;
//------------------------------------------------
otl_connect db; // connect object
otl_connect::otl_initialize();
// initialize OCI environment
try {
db.rlogon("???/???@???"); // connect to Oracle
long rpc;
rpc = otl_cursor::direct_exec(db, "alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS'");
cout << "Alter session : " << rpc << endl;
rpc = otl_cursor::direct_exec(db, "truncate table speedtest");
cout << "Speedtest truncated : " << rpc << endl;
time_t t1 = time(NULL);
insert(db, d);
time_t t2 = time(NULL);
cout << "Runtime: " << t2 - t1 << endl;
db.commit();
} catch(otl_exception& p) { // intercept OTL exceptions
cerr << p.msg <