Database-Benchmark/db-test-sqlite3.pl

354 lines
10 KiB
Perl
Executable File

#!/usr/bin/perl
use DBI;
use Text::CSV;
use Data::Dumper;
use Lingua::EN::Nums2Words;
use Time::HiRes qw/ time /;
use POSIX;
my $csv = Text::CSV->new({binary => 1}) or die "Cannot use CSV: ".Text::CSV->error_diag();
my $dbh = DBI->connect("dbi:SQLite:dbname=".$ENV{"HOME"}."/Desktop/db.sqlite","","");
my $start = time();
my $columnStructure = "id INTEGER";
my $rowCount = 0;
my $columnCount = 0;
my $columnTitles = undef;
open(my $fh, "<".$ENV{"HOME"}."/Desktop/data.csv");
my $sth = $dbh->prepare("BEGIN;");
$sth->execute();
while (my $row = $csv->getline($fh)) {
$rowCount++;
if ($rowCount==1) {
$columnCount = scalar(@$row);
$columnTitles = $row;
for (my $i=0; $i<scalar(@$row); $i++) {
$columnStructure .= ",".$row->[$i]." TEXT";
}
my $sth = $dbh->prepare("CREATE TABLE posts(".$columnStructure.");");
$sth->execute();
next;
}
my @data = ();
push(@data,$rowCount-1);
my $columns = "id";
my $values = "?";
for (my $i=0; $i<$columnCount; $i++) {
$columns .= ",".$columnTitles->[$i];
$values .= ",?";
push(@data,$row->[$i]);
}
my $sth = $dbh->prepare("INSERT INTO posts (".$columns.")VALUES(".$values.");");
$sth->execute(@data);
}
my $sth = $dbh->prepare("COMMIT;");
$sth->execute();
$csv->eof or $csv->error_diag();
close($fh);
my $runTime = sprintf("%.5f", time()-$start);
print "Insert ".$rowCount." rows: ".$runTime."\n";
my $start = time();
my $sth = $dbh->prepare("BEGIN;");
$sth->execute();
my $sth = $dbh->prepare("CREATE TABLE posts_copy AS SELECT * FROM posts;");
$sth->execute();
my $sth = $dbh->prepare("DROP TABLE posts;");
$sth->execute();
my $sth = $dbh->prepare("CREATE VIRTUAL TABLE posts USING fts3(".$columnStructure.");");
$sth->execute();
my $sth = $dbh->prepare("INSERT INTO posts SELECT * FROM posts_copy;");
$sth->execute();
my $sth = $dbh->prepare("DROP TABLE posts_copy;");
$sth->execute();
my $sth = $dbh->prepare("COMMIT;");
$sth->execute();
my $runTime = sprintf("%.5f", time()-$start);
print "Create index: ".$runTime."\n";
my $start = time();
my $sth = $dbh->prepare("SELECT * FROM posts WHERE data MATCH ? LIMIT 100;");
$sth->execute("feet");
while (my $row = $sth->fetchrow_hashref) {
#Do nothing
}
my $runTime = sprintf("%.5f", time()-$start);
print "Search Index: ".$runTime."\n";
my $start = time();
my $sth = $dbh->prepare("SELECT * FROM posts WHERE data LIKE ? LIMIT 100;");
$sth->execute("\%feet\%");
while (my $row = $sth->fetchrow_hashref) {
#Do nothing
}
my $runTime = sprintf("%.5f", time()-$start);
print "Find by string contains: ".$runTime."\n";
my $start = time();
my $sth = $dbh->prepare("SELECT * FROM posts WHERE id=584;");
$sth->execute();
while (my $row = $sth->fetchrow_hashref) {
#Do nothing
}
my $runTime = sprintf("%.5f", time()-$start);
print "Find by id: ".$runTime."\n";
my $sth = $dbh->prepare("DROP TABLE posts;");
$sth->execute();
my $sth = $dbh->prepare("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100));");
$sth->execute();
my $start = time();
for (my $i=0; $i<1000; $i++) {
my $number = $i*135;
my $sth = $dbh->prepare("INSERT INTO t1 (a,b,c)VALUES(?,?,?);");
$sth->execute($i,$number,num2word($number));
}
my $runTime = sprintf("%.5f", time()-$start);
print "1000 INSERTs: ".$runTime."\n";
my $sth = $dbh->prepare("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100));");
$sth->execute();
my $start = time();
my $sth = $dbh->prepare("BEGIN;");
$sth->execute();
for (my $i=0; $i<25000; $i++) {
my $number = $i*135;
my $sth = $dbh->prepare("INSERT INTO t2 (a,b,c)VALUES(?,?,?);");
$sth->execute($i,$number,num2word($number));
}
my $sth = $dbh->prepare("COMMIT;");
$sth->execute();
my $runTime = sprintf("%.5f", time()-$start);
print "25000 INSERTs in a transaction: ".$runTime."\n";
my $sth = $dbh->prepare("CREATE TABLE t3(a INTEGER, b INTEGER, c VARCHAR(100));");
$sth->execute();
my $sth = $dbh->prepare("CREATE INDEX i3 ON t3(c);");
$sth->execute();
my $start = time();
my $sth = $dbh->prepare("BEGIN;");
$sth->execute();
for (my $i=0; $i<25000; $i++) {
my $number = $i*135;
my $sth = $dbh->prepare("INSERT INTO t3 (a,b,c)VALUES(?,?,?);");
$sth->execute($i,$number,num2word($number));
}
my $sth = $dbh->prepare("COMMIT;");
$sth->execute();
my $runTime = sprintf("%.5f", time()-$start);
print "25000 INSERTs into an indexed table: ".$runTime."\n";
my $start = time();
for (my $i=0; $i<100; $i++) {
my $number = $i*100;
my $sth = $dbh->prepare("SELECT count(*), avg(b) FROM t2 WHERE b>=? AND b<?;");
$sth->execute($number,$number+1000);
my $row = $sth->fetchrow_hashref;
}
my $runTime = sprintf("%.5f", time()-$start);
print "100 SELECTs without an index: ".$runTime."\n";
my $start = time();
for (my $i=0; $i<100; $i++) {
my $number = $i;
my $sth = $dbh->prepare("SELECT count(*), avg(b) FROM t2 WHERE c LIKE ?;");
$sth->execute("%".num2word($number)."%");
my $row = $sth->fetchrow_hashref;
}
my $runTime = sprintf("%.5f", time()-$start);
print "100 SELECTs on a string comparison: ".$runTime."\n";
my $start = time();
my $sth = $dbh->prepare("CREATE INDEX i2a ON t2(a);");
$sth->execute();
my $sth = $dbh->prepare("CREATE INDEX i2b ON t2(b);");
$sth->execute();
my $runTime = sprintf("%.5f", time()-$start);
print "Creating an index: ".$runTime."\n";
my $start = time();
for (my $i=0; $i<5000; $i++) {
my $number = $i*100;
my $sth = $dbh->prepare("SELECT count(*), avg(b) FROM t2 WHERE b>=? AND b<?;");
$sth->execute($number,$number+1000);
my $row = $sth->fetchrow_hashref;
}
my $runTime = sprintf("%.5f", time()-$start);
print "5000 SELECTs with an index: ".$runTime."\n";
my $start = time();
my $sth = $dbh->prepare("BEGIN;");
$sth->execute();
for (my $i=0; $i<1000; $i++) {
my $number = $i*10;
my $sth = $dbh->prepare("UPDATE t1 SET b=b*2 WHERE a>=? AND a<?;");
$sth->execute($number,$number+10);
}
my $sth = $dbh->prepare("COMMIT;");
$sth->execute();
my $runTime = sprintf("%.5f", time()-$start);
print "1000 UPDATEs without an index: ".$runTime."\n";
my $start = time();
my $sth = $dbh->prepare("BEGIN;");
$sth->execute();
for (my $i=0; $i<25000; $i++) {
my $number = $i*123;
my $sth = $dbh->prepare("UPDATE t2 SET b=? WHERE a=?;");
$sth->execute($number,$i);
}
my $sth = $dbh->prepare("COMMIT;");
$sth->execute();
my $runTime = sprintf("%.5f", time()-$start);
print "25000 UPDATEs with an index: ".$runTime."\n";
my $start = time();
my $sth = $dbh->prepare("BEGIN;");
$sth->execute();
for (my $i=0; $i<25000; $i++) {
my $number = $i*123;
my $sth = $dbh->prepare("UPDATE t2 SET c=? WHERE a=?;");
$sth->execute(num2word($number),$i);
}
my $sth = $dbh->prepare("COMMIT;");
$sth->execute();
my $runTime = sprintf("%.5f", time()-$start);
print "25000 text UPDATEs with an index: ".$runTime."\n";
my $start = time();
my $sth = $dbh->prepare("BEGIN;");
$sth->execute();
my $sth = $dbh->prepare("INSERT INTO t1 SELECT b,a,c FROM t2;");
$sth->execute();
my $sth = $dbh->prepare("INSERT INTO t2 SELECT b,a,c FROM t1;");
$sth->execute();
my $sth = $dbh->prepare("COMMIT;");
$sth->execute();
my $runTime = sprintf("%.5f", time()-$start);
print "INSERTs from a SELECT: ".$runTime."\n";
my $start = time();
my $sth = $dbh->prepare("DELETE FROM t2 WHERE c LIKE '\%fifty\%';");
$sth->execute();
my $runTime = sprintf("%.5f", time()-$start);
print "DELETE without an index: ".$runTime."\n";
my $start = time();
my $sth = $dbh->prepare("DELETE FROM t2 WHERE a>10 AND a<20000;");
$sth->execute();
my $runTime = sprintf("%.5f", time()-$start);
print "DELETE with an index: ".$runTime."\n";
my $start = time();
my $sth = $dbh->prepare("INSERT INTO t2 SELECT * FROM t1;");
$sth->execute();
my $runTime = sprintf("%.5f", time()-$start);
print "A big INSERT after a big DELETE: ".$runTime."\n";
my $start = time();
my $sth = $dbh->prepare("BEGIN;");
$sth->execute();
my $sth = $dbh->prepare("DELETE FROM t1;");
$sth->execute();
for (my $i=0; $i<12000; $i++) {
my $number = $i*165;
my $sth = $dbh->prepare("INSERT INTO t1 (a,b,c)VALUES(?,?,?);");
$sth->execute($i,$number,num2word($number));
}
my $sth = $dbh->prepare("COMMIT;");
$sth->execute();
my $runTime = sprintf("%.5f", time()-$start);
print "A big DELETE followed by many small INSERTs: ".$runTime."\n";
my $start = time();
my $sth = $dbh->prepare("DROP TABLE t1;");
$sth->execute();
my $sth = $dbh->prepare("DROP TABLE t2;");
$sth->execute();
my $sth = $dbh->prepare("DROP TABLE t3;");
$sth->execute();
my $runTime = sprintf("%.5f", time()-$start);
print "DROP TABLE: ".$runTime."\n";
sub hex2bin {
my $h = shift;
my $hlen = length($h);
return pack("H$hlen", $h);
}
my $sth = $dbh->prepare("CREATE TABLE ips(a VARCHAR(16), b VARCHAR(16), c INTEGER);");
$sth->execute();
for (my $i=0; $i<10; $i++) {
my $binary = hex2bin("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".$i."0");
my $binaryEnd = hex2bin("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".$i."F");
my $sth = $dbh->prepare("INSERT INTO ips (a,b,c)VALUES(?,?,?);");
$sth->execute($binary,$binaryEnd,$i);
}
my $correct = 1;
for (my $i=0; $i<10; $i++) {
my $binary = hex2bin("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".$i."5");
my $sth = $dbh->prepare("SELECT * FROM ips WHERE a<=? AND b>?;");
$sth->execute($binary,$binary);
my $row = $sth->fetchrow_hashref;
unless ($row->{'c'}==$i) {
$correct = 0;
print "Unable to find ".$i." ".$binary." in the database.\n";
}
}
if ($correct) {
print "Binary range seems to work.\n";
}
my $sth = $dbh->prepare("DELETE FROM ips;");
$sth->execute();
my $start = time();
my $sth = $dbh->prepare("BEGIN;");
$sth->execute();
for (my $a=0; $a<10; $a++) {
for (my $b=0; $b<10; $b++) {
for (my $c=0; $c<10; $c++) {
for (my $d=0; $d<10; $d++) {
for (my $e=0; $e<10; $e++) {
for (my $f=0; $f<10; $f++) {
for (my $g=0; $g<10; $g++) {
my $binary = hex2bin("FFFFFFFFFFFFFFFF".$a."F".$b."F".$c."F".$d."F".$e."F".$f."F".$g."FF0");
my $binaryEnd = hex2bin("FFFFFFFFFFFFFFFF".$a."F".$b."F".$c."F".$d."F".$e."F".$f."F".$g."FFF");
my $sth = $dbh->prepare("INSERT INTO ips (a,b)VALUES(?,?);");
$sth->execute($binary,$binaryEnd);
}
}
}
}
}
}
}
my $sth = $dbh->prepare("COMMIT;");
$sth->execute();
my $runTime = sprintf("%.5f", time()-$start);
print "Insert large amount of test IP Addreses: ".$runTime."\n";
my $sth = $dbh->prepare("SELECT COUNT(*) FROM ips;");
$sth->execute();
my $result = $sth->fetchrow_hashref;
print Dumper($result);
my $start = time();
my $binary = hex2bin("FFFFFFFFFFFFFFFF5F7F8F3F9F0F6FF4");
my $sth = $dbh->prepare("SELECT * FROM ips WHERE a<=? AND b>?;");
$sth->execute($binary,$binary);
my $row = $sth->fetchrow_hashref;
print Dumper($row);
my $runTime = sprintf("%.5f", time()-$start);
print "Find one IP Address: ".$runTime."\n";
my $sth = $dbh->prepare("DROP TABLE ips;");
$sth->execute();