test-insert
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:49k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. #!/usr/bin/perl
  2. # Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  3. #
  4. # This library is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU Library General Public
  6. # License as published by the Free Software Foundation; either
  7. # version 2 of the License, or (at your option) any later version.
  8. #
  9. # This library is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. # Library General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU Library General Public
  15. # License along with this library; if not, write to the Free
  16. # Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  17. # MA 02111-1307, USA
  18. #
  19. # Test of creating a simple table and inserting $record_count records in it,
  20. # $opt_loop_count rows in order, $opt_loop_count rows in reverse order and
  21. # $opt_loop_count rows in random order
  22. #
  23. # changes made for Oracle compatibility
  24. # - $limits->{'func_odbc_mod'} is OK from crash-me, but it fails here so set we
  25. #   set it to 0 in server-cfg
  26. # - the default server config runs out of rollback segments, so we added a
  27. #   couple of disconnect/connects to reset
  28. #
  29. ##################### Standard benchmark inits ##############################
  30. use Cwd;
  31. use DBI;
  32. use Benchmark;
  33. use Data::Dumper;
  34. $opt_loop_count=100000; # number of rows/3
  35. $small_loop_count=10; # Loop for full table retrieval
  36. $range_loop_count=$small_loop_count*50;
  37. $many_keys_loop_count=$opt_loop_count;
  38. $opt_read_key_loop_count=$opt_loop_count;
  39. $pwd = cwd(); $pwd = "." if ($pwd eq '');
  40. require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!n";
  41. if ($opt_small_test)
  42. {
  43.   $opt_loop_count/=100;
  44.   $many_keys_loop_count=$opt_loop_count/10;
  45.   $range_loop_count=10;
  46.   $opt_read_key_loop_count=10;
  47. }
  48. elsif ($opt_small_tables)
  49. {
  50.   $opt_loop_count=10000; # number of rows/3
  51.   $many_keys_loop_count=$opt_loop_count;
  52.   $opt_read_key_loop_count=10;
  53. }
  54. elsif ($opt_small_key_tables)
  55. {
  56.   $many_keys_loop_count/=10;
  57. }
  58. if ($opt_loop_count < 100)
  59. {
  60.   $opt_loop_count=100; # Some tests must have some data to work!
  61. }
  62. $range_loop_count=min($opt_loop_count,$range_loop_count);
  63. print "Testing the speed of inserting data into 1 table and do some selects on it.n";
  64. print "The tests are done with a table that has $opt_loop_count rows.nn";
  65. ####
  66. #### Generating random keys
  67. ####
  68. print "Generating random keysn";
  69. $random[$opt_loop_count]=0;
  70. for ($i=0 ; $i < $opt_loop_count ; $i++)
  71. {
  72.   $random[$i]=$i+$opt_loop_count;
  73. }
  74. my $tmpvar=1;
  75. for ($i=0 ; $i < $opt_loop_count ; $i++)
  76. {
  77.   $tmpvar^= ((($tmpvar + 63) + $i)*3 % $opt_loop_count);
  78.   $swap=$tmpvar % $opt_loop_count;
  79.   $tmp=$random[$i]; $random[$i]=$random[$swap]; $random[$swap]=$tmp;
  80. }
  81. $total_rows=$opt_loop_count*3;
  82. ####
  83. ####  Connect and start timeing
  84. ####
  85. $start_time=new Benchmark;
  86. $dbh = $server->connect();
  87. ####
  88. #### Create needed tables
  89. ####
  90. goto keys_test if ($opt_stage == 2);
  91. goto select_test if ($opt_skip_create);
  92. print "Creating tablesn";
  93. $dbh->do("drop table bench1" . $server->{'drop_attr'});
  94. $dbh->do("drop table bench2" . $server->{'drop_attr'});
  95. $dbh->do("drop table bench3" . $server->{'drop_attr'});
  96. do_many($dbh,$server->create("bench1",
  97.      ["id int NOT NULL",
  98.       "id2 int NOT NULL",
  99.       "id3 int NOT NULL",
  100.       "dummy1 char(30)"],
  101.      ["primary key (id,id2)",
  102.      "index ix_id3 (id3)"]));
  103. if ($opt_lock_tables)
  104. {
  105.   $sth = $dbh->do("LOCK TABLES bench1 WRITE") || die $DBI::errstr;
  106. }
  107. ####
  108. #### Insert $total_rows records in order, in reverse order and random.
  109. ####
  110. $loop_time=new Benchmark;
  111. if ($opt_fast_insert)
  112. {
  113.   $query="insert into bench1 values ";
  114. }
  115. else
  116. {
  117.   $query="insert into bench1 (id,id2,id3,dummy1) values ";
  118. }
  119. if ($opt_fast && $server->{transactions})
  120. {
  121.   $dbh->{AutoCommit} = 0;
  122.   print "Transactions enabledn" if ($opt_debug);
  123. }
  124. if (($opt_fast || $opt_fast_insert) && $server->{'limits'}->{'insert_multi_value'})
  125. {
  126.   $query_size=$server->{'limits'}->{'query_size'};
  127.   print "Inserting $opt_loop_count multiple-value rows in ordern";
  128.   $res=$query;
  129.   for ($i=0 ; $i < $opt_loop_count ; $i++)
  130.   {
  131.     $tmp= "($i,$i,$i,'ABCDEFGHIJ'),";
  132.     if (length($tmp)+length($res) < $query_size)
  133.     {
  134.       $res.= $tmp;
  135.     }
  136.     else
  137.     {
  138.       $sth = $dbh->do(substr($res,0,length($res)-1)) or die $DBI::errstr;
  139.       $res=$query . $tmp;
  140.     }
  141.   }
  142.   print "Inserting $opt_loop_count multiple-value rows in reverse ordern";
  143.   for ($i=0 ; $i < $opt_loop_count ; $i++)
  144.   {
  145.     $tmp= "(" . ($total_rows-1-$i) . "," .($total_rows-1-$i) .
  146.       "," .($total_rows-1-$i) . ",'BCDEFGHIJK'),";
  147.     if (length($tmp)+length($res) < $query_size)
  148.     {
  149.       $res.= $tmp;
  150.     }
  151.     else
  152.     {
  153.       $sth = $dbh->do(substr($res,0,length($res)-1)) or die $DBI::errstr;
  154.       $res=$query . $tmp;
  155.     }
  156.   }
  157.   print "Inserting $opt_loop_count multiple-value rows in random ordern";
  158.   for ($i=0 ; $i < $opt_loop_count ; $i++)
  159.   {
  160.     $tmp= "(" . $random[$i] . "," . $random[$i] . "," . $random[$i] .
  161.       ",'CDEFGHIJKL')," or die $DBI::errstr;
  162.     if (length($tmp)+length($res) < $query_size)
  163.     {
  164.       $res.= $tmp;
  165.     }
  166.     else
  167.     {
  168.       $sth = $dbh->do(substr($res,0,length($res)-1)) or die $DBI::errstr;
  169.       $res=$query . $tmp;
  170.     }
  171.   }
  172.   $sth = $dbh->do(substr($res,0,length($res)-1)) or die $DBI::errstr;
  173. }
  174. else
  175. {
  176.   print "Inserting $opt_loop_count rows in ordern";
  177.   for ($i=0 ; $i < $opt_loop_count ; $i++)
  178.   {
  179.     $sth = $dbh->do($query . "($i,$i,$i,'ABCDEFGHIJ')") or die $DBI::errstr;
  180.   }
  181.   print "Inserting $opt_loop_count rows in reverse ordern";
  182.   for ($i=0 ; $i < $opt_loop_count ; $i++)
  183.   {
  184.     $sth = $dbh->do($query . "(" . ($total_rows-1-$i) . "," .
  185.     ($total_rows-1-$i) . "," .
  186.     ($total_rows-1-$i) . ",'BCDEFGHIJK')")
  187.       or die $DBI::errstr;
  188.   }
  189.   print "Inserting $opt_loop_count rows in random ordern";
  190.   for ($i=0 ; $i < $opt_loop_count ; $i++)
  191.   {
  192.     $sth = $dbh->do($query . "(". $random[$i] . "," . $random[$i] .
  193.     "," . $random[$i] . ",'CDEFGHIJKL')") or die $DBI::errstr;
  194.   }
  195. }
  196. if ($opt_fast && $server->{transactions})
  197. {
  198.   $dbh->commit;
  199.   $dbh->{AutoCommit} = 1;
  200. }
  201. $end_time=new Benchmark;
  202. print "Time for insert (" . ($total_rows) . "): " .
  203.   timestr(timediff($end_time, $loop_time),"all") . "nn";
  204. if ($opt_lock_tables)
  205. {
  206.   $sth = $dbh->do("UNLOCK TABLES") || die $DBI::errstr;
  207. }
  208. if ($opt_fast && defined($server->{vacuum}))
  209. {
  210.   $server->vacuum(1,$dbh,"bench1");
  211. }
  212. if ($opt_lock_tables)
  213. {
  214.   $sth = $dbh->do("LOCK TABLES bench1 WRITE") || die $DBI::errstr;
  215. }
  216. ####
  217. #### insert $opt_loop_count records with duplicate id
  218. ####
  219. if ($limits->{'unique_index'})
  220. {
  221.   print "Testing insert of duplicatesn";
  222.   $loop_time=new Benchmark;
  223.   if ($opt_fast && $server->{transactions})
  224.   {
  225.     $dbh->{AutoCommit} = 0;
  226.   }
  227.   for ($i=0 ; $i < $opt_loop_count ; $i++)
  228.   {
  229.     $tmpvar^= ((($tmpvar + 63) + $i)*3 % $opt_loop_count);
  230.     $tmp=$tmpvar % ($total_rows);
  231.     $tmpquery = "$query ($tmp,$tmp,2,'D')";
  232.     if ($dbh->do($tmpquery))
  233.     {
  234.       die "Didn't get an error when inserting duplicate record $tmpn";
  235.     }
  236.   }
  237.   if ($opt_fast && $server->{transactions})
  238.   {
  239.     $dbh->commit;
  240.     $dbh->{AutoCommit} = 1;
  241.   }
  242.   $end_time=new Benchmark;
  243.   print "Time for insert_duplicates (" . ($opt_loop_count) . "): " .
  244.   timestr(timediff($end_time, $loop_time),"all") . "nn";
  245. }
  246. ####
  247. #### Do some selects on the table
  248. ####
  249. select_test:
  250. # ----------------- prepared+executed/prepared*executed tests
  251. print "Test of prepared+execute/once prepared many execute selectsn";
  252. $loop_time=new Benchmark;
  253. for ($i=1 ; $i <= $opt_loop_count ; $i++)
  254. {
  255.   my ($key_value)=$random[$i];
  256.   my ($query)= "select * from bench1 where id=$key_value";  
  257.   print "$queryn" if ($opt_debug);
  258.   $sth = $dbh->prepare($query);
  259.   if (! $sth)
  260.     {
  261.       die "error in prepare select with id = $key_value : $DBI::errstr";
  262.     };
  263.   if (! $sth->execute)  
  264.    {
  265.       die "cannot execute prepare select with id = $key_value : $DBI::errstr";      
  266.    }
  267.   while ($sth->fetchrow_arrayref) { };      
  268.   $sth->finish;
  269. };
  270. $end_time=new Benchmark;
  271. print "Time for prepared_select ($opt_loop_count): " .
  272.     timestr(timediff($end_time, $loop_time),"all") . "n";
  273. $loop_time=new Benchmark;
  274. $query= "select * from bench1 where id=?";  
  275. $sth = $dbh->prepare($query);
  276. if (! $sth)
  277. {
  278.   die "cannot prepare select: $DBI::errstr";
  279. };
  280. for ($i=1 ; $i <= $opt_loop_count ; $i++)
  281. {
  282.   my ($key_value)=$random[$i];
  283.   $sth->bind_param(1,$key_value);
  284.   print "$query , id = $key_valuen" if ($opt_debug);
  285.   if (! $sth->execute)  
  286.    {
  287.       die "cannot execute prepare select with id = $key_value : $DBI::errstr";      
  288.    }
  289.   while ($sth->fetchrow_arrayref) { };      
  290. };
  291. $sth->finish;
  292. $end_time=new Benchmark;
  293. print "Time for once_prepared_select ($opt_loop_count): " .
  294.     timestr(timediff($end_time, $loop_time),"all") . "n";
  295. print "Retrieving data from the tablen";
  296. $loop_time=new Benchmark;
  297. $error=0;
  298. # It's really a small table, so we can try a select on everything
  299. $count=0;
  300. for ($i=1 ; $i <= $small_loop_count ; $i++)
  301. {
  302.   if (($found_rows=fetch_all_rows($dbh,"select id from bench1")) !=
  303.       $total_rows)
  304.   {
  305.     if (!$error++)
  306.     {
  307.       print "Warning: Got $found_rows rows when selecting a whole table of " . ($total_rows) . " rowsnContact the database or DBD author!n";
  308.     }
  309.   }
  310.   $count+=$found_rows;
  311. }
  312. $end_time=new Benchmark;
  313. print "Time for select_big ($small_loop_count:$count): " .
  314.     timestr(timediff($end_time, $loop_time),"all") . "n";
  315. #
  316. # Do a lot of different ORDER BY queries
  317. #
  318. $loop_time=new Benchmark;
  319. $estimated=$rows=0;
  320. for ($i=1 ; $i <= $small_loop_count ; $i++)
  321. {
  322.   $rows+=fetch_all_rows($dbh,"select id,id2 from bench1 order by id,id2",1);
  323.   $end_time=new Benchmark;
  324.   last if ($estimated=predict_query_time($loop_time,$end_time,$i,$i,
  325.  $small_loop_count));
  326. }
  327. if ($estimated)
  328. { print "Estimated time"; }
  329. else
  330. { print "Time"; }
  331. print " for order_by_big_key ($small_loop_count:$rows): " .
  332.   timestr(timediff($end_time, $loop_time),"all") . "n";
  333. $loop_time=new Benchmark;
  334. $estimated=$rows=0;
  335. for ($i=1 ; $i <= $small_loop_count ; $i++)
  336. {
  337.   $rows+=fetch_all_rows($dbh,"select id,id2 from bench1 order by id desc, id2 desc",1);
  338.   $end_time=new Benchmark;
  339.   last if ($estimated=predict_query_time($loop_time,$end_time,$i,$i,
  340.  $small_loop_count));
  341. }
  342. if ($estimated)
  343. { print "Estimated time"; }
  344. else
  345. { print "Time"; }
  346. print " for order_by_big_key_desc ($small_loop_count:$rows): " .
  347.   timestr(timediff($end_time, $loop_time),"all") . "n";
  348. $loop_time=new Benchmark;
  349. $estimated=$rows=0;
  350. for ($i=1 ; $i <= $small_loop_count ; $i++)
  351. {
  352.   $rows+=fetch_all_rows($dbh,"select id from bench1 order by id desc",1);
  353.   $end_time=new Benchmark;
  354.   last if ($estimated=predict_query_time($loop_time,$end_time,$i,$i,
  355.  $small_loop_count));
  356. }
  357. if ($estimated)
  358. { print "Estimated time"; }
  359. else
  360. { print "Time"; }
  361. print " for order_by_big_key_prefix ($small_loop_count:$rows): " .
  362.   timestr(timediff($end_time, $loop_time),"all") . "n";
  363. $loop_time=new Benchmark;
  364. $estimated=$rows=0;
  365. for ($i=1 ; $i <= $small_loop_count ; $i++)
  366. {
  367.   $rows+=fetch_all_rows($dbh,"select id3 from bench1 order by id3",1);
  368.   $end_time=new Benchmark;
  369.   last if ($estimated=predict_query_time($loop_time,$end_time,$i,$i,
  370.  $small_loop_count));
  371. }
  372. if ($estimated)
  373. { print "Estimated time"; }
  374. else
  375. { print "Time"; }
  376. print " for order_by_big_key2 ($small_loop_count:$rows): " .
  377.   timestr(timediff($end_time, $loop_time),"all") . "n";
  378. $sel=$limits->{'order_by_unused'} ? "id2" : "*";
  379. $loop_time=new Benchmark;
  380. $estimated=$rows=0;
  381. for ($i=1 ; $i <= $small_loop_count ; $i++)
  382. {
  383.   $rows+=fetch_all_rows($dbh,"select $sel from bench1 order by id3",1);
  384.   $end_time=new Benchmark;
  385.   last if ($estimated=predict_query_time($loop_time,$end_time,$i,$i,
  386.  $small_loop_count));
  387. }
  388. if ($estimated)
  389. { print "Estimated time"; }
  390. else
  391. { print "Time"; }
  392. print " for order_by_big_key_diff ($small_loop_count:$rows): " .
  393.   timestr(timediff($end_time, $loop_time),"all") . "n";
  394. $sel=$limits->{'order_by_unused'} ? "id" : "*";
  395. $loop_time=new Benchmark;
  396. $estimated=$rows=0;
  397. for ($i=1 ; $i <= $small_loop_count ; $i++)
  398. {
  399.   $rows+=fetch_all_rows($dbh,"select $sel from bench1 order by id2,id3",1);
  400.   $end_time=new Benchmark;
  401.   last if ($estimated=predict_query_time($loop_time,$end_time,$i,$i,
  402.  $small_loop_count));
  403. }
  404. if ($estimated)
  405. { print "Estimated time"; }
  406. else
  407. { print "Time"; }
  408. print " for order_by_big ($small_loop_count:$rows): " .
  409.   timestr(timediff($end_time, $loop_time),"all") . "n";
  410. $sel=$limits->{'order_by_unused'} ? "dummy1" : "dummy1,id3";
  411. $loop_time=new Benchmark;
  412. $estimated=$rows=0;
  413. for ($i=1 ; $i <= $range_loop_count ; $i++)
  414. {
  415.   $start=$opt_loop_count/$range_loop_count*$i;
  416.   $end=$start+$i;
  417.   $rows+=fetch_all_rows($dbh,"select $sel from bench1 where id>=$start and id <= $end order by id3",1);
  418.   $end_time=new Benchmark;
  419.   last if ($estimated=predict_query_time($loop_time,$end_time,$i,$i,
  420.  $range_loop_count));
  421. }
  422. if ($estimated)
  423. { print "Estimated time"; }
  424. else
  425. { print "Time"; }
  426. print " for order_by_range ($range_loop_count:$rows): " .
  427.   timestr(timediff($end_time, $loop_time),"all") . "n";
  428. $sel=$limits->{'order_by_unused'} ? "dummy1" : "dummy1,id";
  429. $loop_time=new Benchmark;
  430. $estimated=$rows=0;
  431. for ($i=1 ; $i <= $range_loop_count ; $i++)
  432. {
  433.   $start=$opt_loop_count/$range_loop_count*$i;
  434.   $end=$start+$i;
  435.   $rows+=fetch_all_rows($dbh,"select $sel from bench1 where id>=$start and id <= $end order by id",1);
  436.   $end_time=new Benchmark;
  437.   last if ($estimated=predict_query_time($loop_time,$end_time,$i,$i,
  438.  $range_loop_count));
  439. }
  440. if ($estimated)
  441. { print "Estimated time"; }
  442. else
  443. { print "Time"; }
  444. print " for order_by_key_prefix ($range_loop_count:$rows): " .
  445.   timestr(timediff($end_time, $loop_time),"all") . "n";
  446. $sel=$limits->{'order_by_unused'} ? "id2" : "id2,id3";
  447. $loop_time=new Benchmark;
  448. $estimated=$rows=0;
  449. for ($i=1 ; $i <= $range_loop_count ; $i++)
  450. {
  451.   $start=$opt_loop_count/$range_loop_count*$i;
  452.   $end=$start+$range_loop_count;
  453.   $rows+=fetch_all_rows($dbh,"select $sel from bench1 where id3>=$start and id3 <= $end order by id3",1);
  454.   $end_time=new Benchmark;
  455.   last if ($estimated=predict_query_time($loop_time,$end_time,$i,$i,
  456.  $range_loop_count));
  457. }
  458. if ($estimated)
  459. { print "Estimated time"; }
  460. else
  461. { print "Time"; }
  462. print " for order_by_key2_diff ($range_loop_count:$rows): " .
  463.   timestr(timediff($end_time, $loop_time),"all") . "n";
  464. #
  465. # Test of select on 2 different keys with or
  466. # (In this case database can only use keys if they do an automatic union).
  467. #
  468. $loop_time=new Benchmark;
  469. $estimated=0;
  470. $rows=0;
  471. $count=0;
  472. for ($i=1 ; $i <= $range_loop_count ; $i++)
  473. {
  474.   my $rnd=$i;
  475.   my $rnd2=$random[$i];
  476.   $rows+=fetch_all_rows($dbh,"select id2 from bench1 where id=$rnd or id3=$rnd2",1);
  477.   $count++;
  478.   $end_time=new Benchmark;
  479.   last if ($estimated=predict_query_time($loop_time,$end_time,$count,$count,
  480.  $range_loop_count));
  481. }
  482. if ($estimated)
  483. { print "Estimated time"; }
  484. else
  485. { print "Time"; }
  486. print " for select_diff_key ($count:$rows): " .
  487.   timestr(timediff($end_time, $loop_time),"all") . "n";
  488. # Test select that is very popular when using ODBC
  489. check_or_range("id","select_range_prefix");
  490. check_or_range("id3","select_range_key2");
  491. # Check reading on direct key on id and id3
  492. check_select_key("*","id","select_key_prefix");
  493. check_select_key2("*","id","id2","select_key");
  494. check_select_key2("id,id2","id","id2","select_key_return_key");
  495. check_select_key("*","id3","select_key2");
  496. check_select_key("id3","id3","select_key2_return_key");
  497. check_select_key("id,id2","id3","select_key2_return_prim");
  498. ####
  499. #### A lot of simple selects on ranges
  500. ####
  501. @Q=("select * from bench1 where !id!=3 or !id!=2 or !id!=1 or !id!=4 or !id!=16 or !id!=10",
  502.     6,
  503.     "select * from bench1 where !id!>=" . ($total_rows-1) ." or !id!<1",
  504.     2,
  505.     "select * from bench1 where !id!>=1 and !id!<=2",
  506.     2,
  507.     "select * from bench1 where (!id!>=1 and !id!<=2) or (!id!>=1 and !id!<=2)",
  508.     2,
  509.     "select * from bench1 where !id!>=1 and !id!<=10 and !id!<=5",
  510.     5,
  511.     "select * from bench1 where (!id!>0 and !id!<2) or !id!>=" . ($total_rows-1),
  512.     2,
  513.     "select * from bench1 where (!id!>0 and !id!<2) or (!id!>= " . ($opt_loop_count/2) . " and !id! <= " . ($opt_loop_count/2+2) . ") or !id! = " . ($opt_loop_count/2-1),
  514.     5,
  515.     "select * from bench1 where (!id!>=5 and !id!<=10) or (!id!>=1 and !id!<=4)",
  516.     10,
  517.     "select * from bench1 where (!id!=1 or !id!=2) and (!id!=3 or !id!=4)",
  518.     0,
  519.     "select * from bench1 where (!id!=1 or !id!=2) and (!id!=2 or !id!=3)",
  520.     1,
  521.     "select * from bench1 where (!id!=1 or !id!=5 or !id!=20 or !id!=40) and (!id!=1 or !id!>=20 or !id!=4)",
  522.     3,
  523.     "select * from bench1 where ((!id!=1 or !id!=3) or (!id!>1 and !id!<3)) and !id!<=2",
  524.     2,
  525.     "select * from bench1 where (!id! >= 0 and !id! < 4) or (!id! >=4 and !id! < 6)",
  526.     6,
  527.     "select * from bench1 where !id! <= -1 or (!id! >= 0 and !id! <= 5) or (!id! >=4 and !id! < 6) or (!id! >=6 and !id! <=7) or (!id!>7 and !id! <= 8)",
  528.     9,
  529.     "select * from bench1 where (!id!>=1 and !id!<=2 or !id!>=4 and !id!<=5) or (!id!>=0 and !id! <=10)",
  530.     11,
  531.     "select * from bench1 where (!id!>=1 and !id!<=2 or !id!>=4 and !id!<=5) or (!id!>2 and !id! <=10)",
  532.     10,
  533.     "select * from bench1 where (!id!>1 or !id! <1) and !id!<=2",
  534.     2,
  535.     "select * from bench1 where !id! <= 2 and (!id!>1 or !id! <=1)",
  536.     3,
  537.     "select * from bench1 where (!id!>=1 or !id! <1) and !id!<=2",
  538.     3,
  539.     "select * from bench1 where (!id!>=1 or !id! <=2) and !id!<=2",
  540.     3
  541.     );
  542. print "nTest of compares with simple rangesn";
  543. check_select_range("id","select_range_prefix");
  544. check_select_range("id3","select_range_key2");
  545. ####
  546. #### Some group queries
  547. ####
  548. if ($limits->{'group_functions'})
  549. {
  550.   $loop_time=new Benchmark;
  551.   $count=1;
  552.   $estimated=0;
  553.   for ($tests=0 ; $tests < $small_loop_count ; $tests++)
  554.   {
  555.     $sth=$dbh->prepare($query="select count(*) from bench1") or die $DBI::errstr;
  556.     $sth->execute or die $sth->errstr;
  557.     if (($sth->fetchrow_array)[0] != $total_rows)
  558.     {
  559.       print "Warning: '$query' returned wrong resultn";
  560.     }
  561.     $sth->finish;
  562.     # min, max in keys are very normal
  563.     $count+=7;
  564.     fetch_all_rows($dbh,"select min(id) from bench1");
  565.     fetch_all_rows($dbh,"select max(id) from bench1");
  566.     fetch_all_rows($dbh,"select sum(id+0.0) from bench1");
  567.     fetch_all_rows($dbh,"select min(id3),max(id3),sum(id3-0.0) from bench1");
  568.     if ($limits->{'group_func_sql_min_str'})
  569.     {
  570.       fetch_all_rows($dbh,"select min(dummy1),max(dummy1) from bench1");
  571.     }
  572.     $count++;
  573.     $sth=$dbh->prepare($query="select count(*) from bench1 where id >= " .
  574.        ($opt_loop_count*2)) or die $DBI::errstr;
  575.     $sth->execute or die $DBI::errstr;
  576.     if (($sth->fetchrow_array)[0] != $opt_loop_count)
  577.     {
  578.       print "Warning: '$query' returned wrong resultn";
  579.     }
  580.     $sth->finish;
  581.     $count++;
  582.     $sth=$dbh->prepare($query="select count(*),sum(id+0.0),min(id),max(id),avg(id-0.0) from bench1") or die $DBI::errstr;
  583.     $sth->execute or die $DBI::errstr;
  584.     @row=$sth->fetchrow_array;
  585.     if ($row[0] != $total_rows ||
  586. int($row[1]+0.5) != int((($total_rows-1)/2*$total_rows)+0.5) ||
  587. $row[2] != 0 ||
  588. $row[3] != $total_rows-1 ||
  589. 1-$row[4]/(($total_rows-1)/2) > 0.001)
  590.     {
  591.       # PostgreSQL 6.3 fails here
  592.       print "Warning: '$query' returned wrong result: @rown";
  593.     }
  594.     $sth->finish;
  595.     if ($limits->{'func_odbc_mod'})
  596.     {
  597.       $tmp="mod(id,10)";
  598.       if ($limits->{'func_extra_%'})
  599.       {
  600. $tmp="id % 10"; # For postgreSQL
  601.       }
  602.       $count++;
  603.       if ($limits->{'group_by_alias'}) {
  604. if (fetch_all_rows($dbh,$query=$server->query("select $tmp as last_digit,count(*) from bench1 group by last_digit")) != 10)
  605. {
  606.   print "Warning: '$query' returned wrong number of rowsn";
  607. }
  608.       } elsif ($limits->{'group_by_position'}) {
  609. if (fetch_all_rows($dbh,$query=$server->query("select $tmp,count(*) from bench1 group by 1")) != 10)
  610. {
  611.   print "Warning: '$query' returned wrong number of rowsn";
  612. }
  613.       }
  614.     }
  615.     if ($limits->{'order_by_position'} && $limits->{'group_by_position'})
  616.     {
  617.       $count++;
  618.       if (fetch_all_rows($dbh, $query="select id,id3,dummy1 from bench1 where id < 100+$count-$count group by id,id3,dummy1 order by id desc,id3,dummy1") != 100)
  619.       {
  620. print "Warning: '$query' returned wrong number of rowsn";
  621.       }
  622.     }
  623.     $end_time=new Benchmark;
  624.     last if ($estimated=predict_query_time($loop_time,$end_time,$count,$tests,
  625.    $small_loop_count));
  626.   }
  627.   print_time($estimated);
  628.   print " for select_group ($count): " .
  629.       timestr(timediff($end_time, $loop_time),"all") . "n";
  630.   $loop_time=new Benchmark;
  631.   $count=$estimated=0;
  632.   for ($tests=1 ; $tests <= $range_loop_count*5 ; $tests++)
  633.   {
  634.     $count+=6;
  635.     fetch_all_rows($dbh,"select min(id) from bench1");
  636.     fetch_all_rows($dbh,"select max(id) from bench1");
  637.     fetch_all_rows($dbh,"select min(id2) from bench1 where id=$tests");
  638.     fetch_all_rows($dbh,"select max(id2) from bench1 where id=$tests");
  639.     if ($limits->{'group_func_sql_min_str'})
  640.     {
  641.       fetch_all_rows($dbh,"select min(dummy1) from bench1 where id=$tests");
  642.       fetch_all_rows($dbh,"select max(dummy1) from bench1 where id=$tests");
  643.     }
  644.     $end_time=new Benchmark;
  645.     last if ($estimated=predict_query_time($loop_time,$end_time,$count,$tests,
  646.    $range_loop_count*5));
  647.   }
  648.   if ($estimated)
  649.   { print "Estimated time"; }
  650.   else
  651.   { print "Time"; }
  652.   print " for min_max_on_key ($count): " .
  653.       timestr(timediff($end_time, $loop_time),"all") . "n";
  654.   $loop_time=new Benchmark;
  655.   $count=$estimated=0;
  656.   for ($tests=1 ; $tests <= $small_loop_count ; $tests++)
  657.   {
  658.     $count+=6;
  659.     fetch_all_rows($dbh,"select min(id2) from bench1");
  660.     fetch_all_rows($dbh,"select max(id2) from bench1");
  661.     fetch_all_rows($dbh,"select min(id3) from bench1 where id2=$tests");
  662.     fetch_all_rows($dbh,"select max(id3) from bench1 where id2=$tests");
  663.     if ($limits->{'group_func_sql_min_str'})
  664.     {
  665.       fetch_all_rows($dbh,"select min(dummy1) from bench1 where id2=$tests");
  666.       fetch_all_rows($dbh,"select max(dummy1) from bench1 where id2=$tests");
  667.     }
  668.     $end_time=new Benchmark;
  669.     last if ($estimated=predict_query_time($loop_time,$end_time,$count,$tests,
  670.    $range_loop_count));
  671.   }
  672.   if ($estimated)
  673.   { print "Estimated time"; }
  674.   else
  675.   { print "Time"; }
  676.   print " for min_max ($count): " .
  677.       timestr(timediff($end_time, $loop_time),"all") . "n";
  678.   $loop_time=new Benchmark;
  679.   $count=0;
  680.   $total=$opt_loop_count*3;
  681.   for ($tests=0 ; $tests < $total ; $tests+=$total/100)
  682.   {
  683.     $count+=1;
  684.     fetch_all_rows($dbh,"select count(id) from bench1 where id < $tests");
  685.   }
  686.   $end_time=new Benchmark;
  687.   print "Time for count_on_key ($count): " .
  688.       timestr(timediff($end_time, $loop_time),"all") . "n";
  689.   $loop_time=new Benchmark;
  690.   $count=0;
  691.   for ($tests=0 ; $tests < $total ; $tests+=$total/100)
  692.   {
  693.     $count+=1;
  694.     fetch_all_rows($dbh,"select count(dummy1) from bench1 where id2 < $tests");
  695.   }
  696.   $end_time=new Benchmark;
  697.   print "Time for count ($count): " .
  698.       timestr(timediff($end_time, $loop_time),"all") . "n";
  699.   if ($limits->{'group_distinct_functions'})
  700.   {
  701.     $loop_time=new Benchmark;
  702.     $count=$estimated=0;
  703.     for ($tests=1 ; $tests <= $small_loop_count ; $tests++)
  704.     {
  705.       $count+=2;
  706.       fetch_all_rows($dbh,"select count(distinct dummy1) from bench1");
  707.       fetch_all_rows($dbh,"select dummy1,count(distinct id) from bench1 group by dummy1");
  708.       $end_time=new Benchmark;
  709.       last if ($estimated=predict_query_time($loop_time,$end_time,$count,$tests,
  710.      $small_loop_count));
  711.     }
  712.     if ($estimated)
  713.     { print "Estimated time"; }
  714.     else
  715.     { print "Time"; }
  716.     print " for count_distinct_big ($count): " .
  717.     timestr(timediff($end_time, $loop_time),"all") . "n";
  718.   }
  719. }
  720. if ($server->small_rollback_segment())
  721. {
  722.   $dbh->disconnect; # close connection
  723.   $dbh = $server->connect();
  724. }
  725. ####
  726. #### Some updates on the table
  727. ####
  728. $loop_time=new Benchmark;
  729. if ($limits->{'functions'})
  730. {
  731.   print "nTesting update of keys with functionsn";
  732.   my $update_loop_count=$opt_loop_count/2;
  733.   for ($i=0 ; $i < $update_loop_count ; $i++)
  734.   {
  735.     my $tmp=$opt_loop_count+$random[$i]; # $opt_loop_count*2 <= $tmp < $total_rows
  736.     $sth = $dbh->do("update bench1 set id3=-$tmp where id3=$tmp") or die $DBI::errstr;
  737.   }
  738.   $end_time=new Benchmark;
  739.   print "Time for update_of_key ($update_loop_count):  " .
  740.     timestr(timediff($end_time, $loop_time),"all") . "n";
  741.   if ($opt_lock_tables)
  742.   {
  743.     do_query($dbh,"UNLOCK TABLES");
  744.   }
  745.   if ($opt_fast && defined($server->{vacuum}))
  746.   {
  747.     $server->vacuum(1,$dbh,"bench1");
  748.   }
  749.   if ($opt_lock_tables)
  750.   {
  751.     $sth = $dbh->do("LOCK TABLES bench1 WRITE") || die $DBI::errstr;
  752.   }
  753.   if ($server->small_rollback_segment())
  754.   {
  755.     $dbh->disconnect; # close connection
  756.     $dbh = $server->connect();
  757.   }
  758.   $loop_time=new Benchmark;
  759.   $count=0;
  760.   $step=int($opt_loop_count/$range_loop_count+1);
  761.   for ($i= 0 ; $i < $opt_loop_count ; $i+= $step)
  762.   {
  763.     $count++;
  764.     $sth=$dbh->do("update bench1 set id3= 0-id3 where id3 >= 0 and id3 <= $i") or die $DBI::errstr;
  765.   }
  766.   if ($server->small_rollback_segment())
  767.   {
  768.     $dbh->disconnect; # close connection
  769.     $dbh = $server->connect();
  770.   }
  771.   $count++;
  772.   $sth=$dbh->do("update bench1 set id3= 0-id3 where id3 >= 0 and id3 < $opt_loop_count") or die $DBI::errstr;
  773.   if ($server->small_rollback_segment())
  774.   {
  775.     $dbh->disconnect; # close connection
  776.     $dbh = $server->connect();
  777.   }
  778.   $count++;
  779.   $sth=$dbh->do("update bench1 set id3= 0-id3 where id3 >= $opt_loop_count and id3 < ". ($opt_loop_count*2)) or die $DBI::errstr;
  780.   #
  781.   # Check that everything was updated
  782.   # In principle we shouldn't time this in the update loop..
  783.   #
  784.   if ($server->small_rollback_segment())
  785.   {
  786.     $dbh->disconnect; # close connection
  787.     $dbh = $server->connect();
  788.   }
  789.   $row_count=0;
  790.   if (($sth=$dbh->prepare("select count(*) from bench1 where id3>=0"))
  791.       && $sth->execute)
  792.   {
  793.     ($row_count)=$sth->fetchrow;
  794.   }
  795.   $result=1 + $opt_loop_count-$update_loop_count;
  796.   if ($row_count != $result)
  797.   {
  798.     print "Warning: Update check returned $row_count instead of $resultn";
  799.   }
  800.   $sth->finish;
  801.   if ($server->small_rollback_segment())
  802.   {
  803.     $dbh->disconnect; # close connection
  804.     $dbh = $server->connect();
  805.   }
  806.   #restore id3 to 0 <= id3 < $total_rows/10 or 0<= id3 < $total_rows
  807.   my $func=($limits->{'func_odbc_floor'}) ? "floor((0-id3)/20)" : "0-id3";
  808.   $count++;
  809.   $sth=$dbh->do($query="update bench1 set id3=$func where id3<0") or die $DBI::errstr;
  810.   $end_time=new Benchmark;
  811.   print "Time for update_of_key_big ($count): " .
  812.     timestr(timediff($end_time, $loop_time),"all") . "nn";
  813. }
  814. else
  815. {
  816.   print "nTesting update of keys in loopsn";
  817.   #
  818.   # This is for mSQL that doesn't have functions. Do we really need this ????
  819.   #
  820.   $sth=$dbh->prepare("select id3 from bench1 where id3 >= 0") or die $DBI::errstr;
  821.   $sth->execute or die $DBI::errstr;
  822.   $count=0;
  823.   while (@tmp = $sth->fetchrow_array)
  824.   {
  825.     my $tmp1 = "-$tmp[0]";
  826.     my $sth1 = $dbh->do("update bench1 set id3 = $tmp1 where id3 = $tmp[0]");
  827.     $count++;
  828.     $end_time=new Benchmark;
  829.     if (($end_time->[0] - $loop_time->[0]) > $opt_time_limit)
  830.     {
  831.       print "note: Aborting update loop because of timeoutn";
  832.       last;
  833.     }
  834.   }
  835.   $sth->finish;
  836.   # Check that everything except id3=0 was updated
  837.   # In principle we shouldn't time this in the update loop..
  838.   #
  839.   if (fetch_all_rows($dbh,$query="select * from bench1 where id3>=0") != 1)
  840.   {
  841.     if ($count == $total_rows)
  842.     {
  843.       print "Warning: Wrong information after update: Found '$row_count' rows, but should have been: 1n";
  844.     }
  845.   }
  846.   #restore id3 to 0 <= id3 < $total_rows
  847.   $sth=$dbh->prepare("select id3 from bench1 where id3 < 0") or die $DBI::errstr;
  848.   $sth->execute or die $DBI::errstr;
  849.   while (@tmp = $sth->fetchrow_array)
  850.   {
  851.     $count++;
  852.     my $tmp1 = floor((0-$tmp[0])/10);
  853.     my $sth1 = $dbh->do("update bench1 set id3 = $tmp1 where id3 = $tmp[0]");
  854.   }
  855.   $sth->finish;
  856.   $end_time=new Benchmark;
  857.   $estimated=predict_query_time($loop_time,$end_time,$count,$count,
  858. $opt_loop_count*6);
  859.   if ($estimated)
  860.   { print "Estimated time"; }
  861.   else
  862.   { print "Time"; }
  863.   print " for update_of_key ($count): " .
  864.     timestr(timediff($end_time, $loop_time),"all") . "nn";
  865. }
  866. if ($opt_fast && defined($server->{vacuum}))
  867. {
  868.   if ($opt_lock_tables)
  869.   {
  870.     do_query($dbh,"UNLOCK TABLES");
  871.   }
  872.   $server->vacuum(1,$dbh,"bench1");
  873.   if ($opt_lock_tables)
  874.   {
  875.     $sth = $dbh->do("LOCK TABLES bench1 WRITE") || die $DBI::errstr;
  876.   }
  877. }
  878. #
  879. # Testing some simple updates
  880. #
  881. print "Testing update with keyn";
  882. $loop_time=new Benchmark;
  883. for ($i=0 ; $i < $opt_loop_count*3 ; $i++)
  884. {
  885.   $sth = $dbh->do("update bench1 set dummy1='updated' where id=$i and id2=$i") or die $DBI::errstr;
  886. }
  887. $end_time=new Benchmark;
  888. print "Time for update_with_key (" . ($opt_loop_count*3) . "):  " .
  889.   timestr(timediff($end_time, $loop_time),"all") . "n";
  890. $loop_time=new Benchmark;
  891. $count=0;
  892. for ($i=1 ; $i < $opt_loop_count*3 ; $i+=3)
  893. {
  894.   $sth = $dbh->do("update bench1 set dummy1='updated' where id=$i") or die $DBI::errstr;
  895.   $end_time=new Benchmark;
  896.   last if ($estimated=predict_query_time($loop_time,$end_time,$i,$tests,
  897.  $opt_loop_count));
  898. }
  899. if ($estimated)
  900. { print "Estimated time"; }
  901. else
  902. { print "Time"; }
  903. print " for update_with_key_prefix (" . ($opt_loop_count) . "):  " .
  904.   timestr(timediff($end_time, $loop_time),"all") . "n";
  905. print "nTesting update of all rowsn";
  906. $loop_time=new Benchmark;
  907. for ($i=0 ; $i < $small_loop_count ; $i++)
  908. {
  909.   $sth = $dbh->do("update bench1 set dummy1='updated $i'") or die $DBI::errstr;
  910. }
  911. $end_time=new Benchmark;
  912. print "Time for update_big ($small_loop_count):  " .
  913.   timestr(timediff($end_time, $loop_time),"all") . "n";
  914. #
  915. # Testing left outer join
  916. #
  917. if ($limits->{'func_odbc_floor'} && $limits->{'left_outer_join'})
  918. {
  919.   if ($opt_lock_tables)
  920.   {
  921.     $sth = $dbh->do("LOCK TABLES bench1 a READ, bench1 b READ") || die $DBI::errstr;
  922.   }
  923.   print "nTesting left outer joinn";
  924.   $loop_time=new Benchmark;
  925.   $count=0;
  926.   for ($i=0 ; $i < $small_loop_count ; $i++)
  927.   {
  928.     $count+=fetch_all_rows($dbh,"select count(*) from bench1 as a left outer join bench1 as b on (a.id2=b.id3)");
  929.   }
  930.   $end_time=new Benchmark;
  931.   print "Time for outer_join_on_key ($small_loop_count:$count):  " .
  932.     timestr(timediff($end_time, $loop_time),"all") . "n";
  933.   $loop_time=new Benchmark;
  934.   $count=0;
  935.   for ($i=0 ; $i < $small_loop_count ; $i++)
  936.   {
  937.     $count+=fetch_all_rows($dbh,"select count(a.dummy1),count(b.dummy1) from bench1 as a left outer join bench1 as b on (a.id2=b.id3)");
  938.   }
  939.   $end_time=new Benchmark;
  940.   print "Time for outer_join ($small_loop_count:$count):  " .
  941.     timestr(timediff($end_time, $loop_time),"all") . "n";
  942.   $count=0;
  943.   $loop_time=new Benchmark;
  944.   for ($i=0 ; $i < $small_loop_count ; $i++)
  945.   {
  946.     $count+=fetch_all_rows($dbh,"select count(a.dummy1),count(b.dummy1) from bench1 as a left outer join bench1 as b on (a.id2=b.id3) where b.id3 is not null");
  947.   }
  948.   $end_time=new Benchmark;
  949.   print "Time for outer_join_found ($small_loop_count:$count):  " .
  950.     timestr(timediff($end_time, $loop_time),"all") . "n";
  951.   $count=$estimated=0;
  952.   $loop_time=new Benchmark;
  953.   for ($i=1 ; $i <= $small_loop_count ; $i++)
  954.   {
  955.     $count+=fetch_all_rows($dbh,"select count(a.dummy1),count(b.dummy1) from bench1 as a left outer join bench1 as b on (a.id2=b.id3) where b.id3 is null");
  956.     $end_time=new Benchmark;
  957.     last if ($estimated=predict_query_time($loop_time,$end_time,
  958.    $count,$i,
  959.    $range_loop_count));
  960.   }
  961.   if ($estimated)
  962.   { print "Estimated time"; }
  963.   else
  964.   { print "Time"; }
  965.   print " for outer_join_not_found ($range_loop_count:$count):  " .
  966.     timestr(timediff($end_time, $loop_time),"all") . "n";
  967.   if ($opt_lock_tables)
  968.   {
  969.     $sth = $dbh->do("LOCK TABLES bench1 WRITE") || die $DBI::errstr;
  970.   }
  971. }
  972. if ($server->small_rollback_segment())
  973. {
  974.   $dbh->disconnect; # close connection
  975.   $dbh = $server->connect();
  976. }
  977. ###
  978. ### Test speed of IN( value list)
  979. ###
  980. if ($limits->{'left_outer_join'})
  981. {
  982.   if ($opt_lock_tables)
  983.   {
  984.     $sth = $dbh->do("UNLOCK TABLES") || die $DBI::errstr;
  985.   }
  986.   print "n";
  987.   do_many($dbh,$server->create("bench2",
  988.        ["id int NOT NULL"],
  989.        ["primary key (id)"]));
  990.   $max_tests=min(($limits->{'query_size'}-50)/6, $opt_loop_count);
  991.   if ($opt_lock_tables)
  992.   {
  993.     $sth = $dbh->do("LOCK TABLES bench1 READ, bench2 WRITE") ||
  994.       die $DBI::errstr;
  995.   }
  996.   test_where_in("bench1","bench2","id",1,10);
  997.   test_where_in("bench1","bench2","id",11,min(100,$max_tests));
  998.   test_where_in("bench1","bench2","id",101,min(1000,$max_tests));
  999.   if ($opt_lock_tables)
  1000.   {
  1001.     $sth = $dbh->do("UNLOCK TABLES") || die $DBI::errstr;
  1002.   }
  1003.   $sth = $dbh->do("DROP TABLE bench2" . $server->{'drop_attr'}) ||
  1004.     die $DBI::errstr;
  1005.   if ($opt_lock_tables)
  1006.   {
  1007.     $sth = $dbh->do("LOCK TABLES bench1 WRITE") || die $DBI::errstr;
  1008.   }
  1009. }
  1010. ####
  1011. #### Test INSERT INTO ... SELECT
  1012. ####
  1013. if ($limits->{'insert_select'})
  1014. {
  1015.   if ($opt_lock_tables)
  1016.   {
  1017.     $sth = $dbh->do("UNLOCK TABLES") || die $DBI::errstr;
  1018.   }
  1019.   print "nTesting INSERT INTO ... SELECTn";
  1020.   do_many($dbh,$server->create("bench2",
  1021.        ["id int NOT NULL",
  1022. "id2 int NOT NULL",
  1023. "id3 int NOT NULL",
  1024. "dummy1 char(30)"],
  1025.        ["primary key (id,id2)"]));
  1026.   do_many($dbh,$server->create("bench3",
  1027.        ["id int NOT NULL",
  1028. "id2 int NOT NULL",
  1029. "id3 int NOT NULL",
  1030. "dummy1 char(30)"],
  1031.        ["primary key (id,id2)",
  1032. "index index_id3 (id3)"]));
  1033.   $loop_time=new Benchmark;
  1034.   $sth = $dbh->do("INSERT INTO bench2 SELECT * from bench1") ||
  1035.     die $DBI::errstr;
  1036.   $end_time=new Benchmark;
  1037.   print "Time for insert_select_1_key (1):  " .
  1038.     timestr(timediff($end_time, $loop_time),"all") . "n";
  1039.   $loop_time=new Benchmark;
  1040.   $sth = $dbh->do("INSERT INTO bench3 SELECT * from bench1") ||
  1041.     die $DBI::errstr;
  1042.   $end_time=new Benchmark;
  1043.   print "Time for insert_select_2_keys (1):  " .
  1044.     timestr(timediff($end_time, $loop_time),"all") . "n";
  1045.   $loop_time=new Benchmark;
  1046.   $sth = $dbh->do("DROP TABLE bench2" . $server->{'drop_attr'}) ||
  1047.     die $DBI::errstr;
  1048.   $sth = $dbh->do("DROP TABLE bench3" . $server->{'drop_attr'}) ||
  1049.     die $DBI::errstr;
  1050.   $end_time=new Benchmark;
  1051.   print "Time for drop table(2): " .
  1052.     timestr(timediff($end_time, $loop_time),"all") . "n";
  1053.   if ($opt_fast && defined($server->{vacuum}))
  1054.   {
  1055.     $server->vacuum(1,$dbh);
  1056.   }
  1057.   if ($server->small_rollback_segment())
  1058.   {
  1059.     $dbh->disconnect; # close connection
  1060.     $dbh = $server->connect();
  1061.   }
  1062.   if ($opt_lock_tables)
  1063.   {
  1064.     $sth = $dbh->do("LOCK TABLES bench1 WRITE") || die $DBI::errstr;
  1065.   }
  1066. }
  1067. ####
  1068. #### Do some deletes on the table
  1069. ####
  1070. if (!$opt_skip_delete)
  1071. {
  1072.   print "nTesting deleten";
  1073.   $loop_time=new Benchmark;
  1074.   $count=0;
  1075.   for ($i=0 ; $i < $opt_loop_count ; $i+=10)
  1076.   {
  1077.     $count++;
  1078.     $tmp=$opt_loop_count+$random[$i]; # $opt_loop_count*2 <= $tmp < $total_rows
  1079.     $dbh->do("delete from bench1 where id3=$tmp") or die $DBI::errstr;
  1080.   }
  1081.   $end_time=new Benchmark;
  1082.   print "Time for delete_key ($count): " .
  1083.     timestr(timediff($end_time, $loop_time),"all") . "n";
  1084.   if ($server->small_rollback_segment())
  1085.   {
  1086.     $dbh->disconnect; # close connection
  1087.     $dbh = $server->connect();
  1088.   }
  1089.   $count=0;
  1090.   $loop_time=new Benchmark;
  1091.   for ($i= 0 ; $i < $opt_loop_count ; $i+=$opt_loop_count/10)
  1092.   {
  1093.     $sth=$dbh->do("delete from bench1 where id3 >= 0 and id3 <= $i") or die $DBI::errstr;
  1094.     $count++;
  1095.   }
  1096.   $count+=2;
  1097.   if ($server->small_rollback_segment())
  1098.   {
  1099.     $dbh->disconnect; # close connection
  1100.     $dbh = $server->connect();
  1101.   }
  1102.   $sth=$dbh->do("delete from bench1 where id3 >= 0 and id3 <= $opt_loop_count") or die $DBI::errstr;
  1103.   if ($server->small_rollback_segment())
  1104.   {
  1105.     $dbh->disconnect; # close connection
  1106.     $dbh = $server->connect();
  1107.   }
  1108.   $sth=$dbh->do("delete from bench1 where id >= $opt_loop_count and id <= " . ($opt_loop_count*2) ) or die $DBI::errstr;
  1109.   if ($server->small_rollback_segment())
  1110.   {
  1111.     $dbh->disconnect; # close connection
  1112.     $dbh = $server->connect();
  1113.   }
  1114.   if ($opt_fast)
  1115.   {
  1116.     $sth=$dbh->do("delete from bench1") or die $DBI::errstr;
  1117.   }
  1118.   else
  1119.   {
  1120.     $sth = $dbh->do("delete from bench1 where id3 < " . ($total_rows)) or die $DBI::errstr;
  1121.   }
  1122.   $end_time=new Benchmark;
  1123.   print "Time for delete_range ($count): " .
  1124.     timestr(timediff($end_time, $loop_time),"all") . "nn";
  1125.   if ($opt_lock_tables)
  1126.   {
  1127.     $sth = $dbh->do("UNLOCK TABLES") || die $DBI::errstr;
  1128.   }
  1129.   $sth = $dbh->do("drop table bench1" . $server->{'drop_attr'}) or die $DBI::errstr;
  1130. }
  1131. if ($server->small_rollback_segment())
  1132. {
  1133.   $dbh->disconnect; # close connection
  1134.   $dbh = $server->connect();
  1135. }
  1136. if ($opt_fast && defined($server->{vacuum}))
  1137. {
  1138.   $server->vacuum(1,$dbh);
  1139. }
  1140. keys_test:
  1141. #
  1142. # Test of insert in table with many keys
  1143. # This test assumes that the server really create the keys!
  1144. #
  1145. my @fields=(); my @keys=();
  1146. $keys=min($limits->{'max_index'},16);   # 16 is more than enough
  1147. $seg= min($limits->{'max_index_parts'},$keys,16); # 16 is more than enough
  1148. print "Insert into table with $keys keys and with a primary key with $seg partsn";
  1149. # Make keys on the most important types
  1150. @types=(0,0,0,1,0,0,0,1,1,1,1,1,1,1,1,1,1); # A 1 for each char field
  1151. push(@fields,"field1 tinyint not null");
  1152. push(@fields,"field_search tinyint not null");
  1153. push(@fields,"field2 mediumint not null");
  1154. push(@fields,"field3 smallint not null");
  1155. push(@fields,"field4 char(16) not null");
  1156. push(@fields,"field5 integer not null");
  1157. push(@fields,"field6 float not null");
  1158. push(@fields,"field7 double not null");
  1159. for ($i=8 ; $i <= $keys ; $i++)
  1160. {
  1161.   push(@fields,"field$i char(6) not null"); # Should be relatively fair
  1162. }
  1163. # First key contains many segments
  1164. $query="primary key (";
  1165. for ($i= 1 ; $i <= $seg ; $i++)
  1166. {
  1167.   $query.= "field$i,";
  1168. }
  1169. substr($query,-1)=")";
  1170. push (@keys,$query);
  1171. push (@keys,"index index2 (field_search)");
  1172. #Create other keys
  1173. for ($i=3 ; $i <= $keys ; $i++)
  1174. {
  1175.   push(@keys,"index index$i (field$i)");
  1176. }
  1177. do_many($dbh,$server->create("bench1",@fields,@keys));
  1178. if ($opt_lock_tables)
  1179. {
  1180.   $dbh->do("LOCK TABLES bench1 WRITE") || die $DBI::errstr;
  1181. }
  1182. if ($server->small_rollback_segment())
  1183. {
  1184.   $dbh->disconnect; # close connection
  1185.   $dbh = $server->connect();
  1186. }
  1187. $loop_time=new Benchmark;
  1188. if ($opt_fast && $server->{transactions})
  1189. {
  1190.   $dbh->{AutoCommit} = 0;
  1191. }
  1192. $fields=$#fields;
  1193. if (($opt_fast || $opt_fast_insert) && $server->{'limits'}->{'insert_multi_value'})
  1194. {
  1195.   $query_size=$server->{'limits'}->{'query_size'};
  1196.   $query="insert into bench1 values ";
  1197.   $res=$query;
  1198.   for ($i=0; $i < $many_keys_loop_count; $i++)
  1199.   {
  1200.     $id= $i & 127;
  1201.     $rand=$random[$i];
  1202.     $tmp="($id,$id,$rand," . ($i & 32766) . ",'ABCDEF$rand',0,$rand,$rand.0,";
  1203.     for ($j=8; $j <= $fields ; $j++)
  1204.     {
  1205.       $tmp.= ($types[$j] == 0) ? "$rand," : "'$rand',";
  1206.     }
  1207.     substr($tmp,-1)=")";
  1208.     if (length($tmp)+length($res) < $query_size)
  1209.     {
  1210.       $res.= $tmp . ",";
  1211.     }
  1212.     else
  1213.     {
  1214.       $sth = $dbh->do(substr($res,0,length($res)-1)) or die $DBI::errstr;
  1215.       $res=$query . $tmp . ",";
  1216.     }
  1217.   }
  1218.   $sth = $dbh->do(substr($res,0,length($res)-1)) or die $DBI::errstr;
  1219. }
  1220. else
  1221. {
  1222.   for ($i=0; $i < $many_keys_loop_count; $i++)
  1223.   {
  1224.     $id= $i & 127;
  1225.     $rand=$random[$i];
  1226.     $query="insert into bench1 values ($id,$id,$rand," . ($i & 32767) .
  1227.       ",'ABCDEF$rand',0,$rand,$rand.0,";
  1228.     for ($j=8; $j <= $fields ; $j++)
  1229.     {
  1230.       $query.= ($types[$j] == 0) ? "$rand," : "'$rand',";
  1231.     }
  1232.     substr($query,-1)=")";
  1233.     print "query1: $queryn" if ($opt_debug);
  1234.     $dbh->do($query) or die "Got error $DBI::errstr with query: $queryn";
  1235.   }
  1236. }
  1237. if ($opt_fast && $server->{transactions})
  1238. {
  1239.   $dbh->commit;
  1240.   $dbh->{AutoCommit} = 1;
  1241. }
  1242. $end_time=new Benchmark;
  1243. print "Time for insert_key ($many_keys_loop_count): " .
  1244.   timestr(timediff($end_time, $loop_time),"all") . "nn";
  1245. if ($server->small_rollback_segment())
  1246. {
  1247.   $dbh->disconnect; # close connection
  1248.   $dbh = $server->connect();
  1249. }
  1250. if ($opt_fast && defined($server->{vacuum}))
  1251. {
  1252.   if ($opt_lock_tables)
  1253.   {
  1254.     do_query($dbh,"UNLOCK TABLES");
  1255.   }
  1256.   $server->vacuum(1,$dbh,"bench1");
  1257.   if ($opt_lock_tables)
  1258.   {
  1259.     $sth = $dbh->do("LOCK TABLES bench1 WRITE") || die $DBI::errstr;
  1260.   }
  1261. }
  1262. #
  1263. # update one key of the above
  1264. #
  1265. print "Testing update of keysn";
  1266. $loop_time=new Benchmark;
  1267. if ($opt_fast && $server->{transactions})
  1268. {
  1269.   $dbh->{AutoCommit} = 0;
  1270. }
  1271. for ($i=0 ; $i< 256; $i++)
  1272. {
  1273.   $dbh->do("update bench1 set field5=1 where field_search=$i")
  1274.     or die "Got error $DBI::errstr with query: update bench1 set field5=1 where field_search=$in";
  1275. }
  1276. if ($opt_fast && $server->{transactions})
  1277. {
  1278.   $dbh->commit;
  1279.   $dbh->{AutoCommit} = 1;
  1280. }
  1281. $end_time=new Benchmark;
  1282. print "Time for update_of_primary_key_many_keys (256): " .
  1283.   timestr(timediff($end_time, $loop_time),"all") . "nn";
  1284. if ($server->small_rollback_segment())
  1285. {
  1286.   $dbh->disconnect; # close connection
  1287.   $dbh = $server->connect();
  1288. }
  1289. if ($opt_fast && defined($server->{vacuum}))
  1290. {
  1291.   if ($opt_lock_tables)
  1292.   {
  1293.     do_query($dbh,"UNLOCK TABLES");
  1294.   }
  1295.   $server->vacuum(1,$dbh,"bench1");
  1296.   if ($opt_lock_tables)
  1297.   {
  1298.     $sth = $dbh->do("LOCK TABLES bench1 WRITE") || die $DBI::errstr;
  1299.   }
  1300. }
  1301. if ($server->small_rollback_segment())
  1302. {
  1303.   $dbh->disconnect; # close connection
  1304.   $dbh = $server->connect();
  1305. }
  1306. #
  1307. # Delete everything from table
  1308. #
  1309. print "Deleting rows from the tablen";
  1310. $loop_time=new Benchmark;
  1311. $count=0;
  1312. for ($i=0 ; $i < 128 ; $i++)
  1313. {
  1314.   $count++;
  1315.   $dbh->do("delete from bench1 where field_search = $i") or die $DBI::errstr;
  1316. }
  1317. $end_time=new Benchmark;
  1318. print "Time for delete_big_many_keys ($count): " .
  1319. timestr(timediff($end_time, $loop_time),"all") . "nn";
  1320. if ($opt_lock_tables)
  1321. {
  1322.   $sth = $dbh->do("UNLOCK TABLES") || die $DBI::errstr;
  1323. }
  1324. print "Deleting everything from tablen";
  1325. $count=1;
  1326. if ($opt_fast)
  1327. {
  1328.   $query= ($limits->{'truncate_table'} ? "truncate table bench1" :
  1329.      "delete from bench1");
  1330.   $dbh->do($query) or die $DBI::errstr;
  1331. }
  1332. else
  1333. {
  1334.   $dbh->do("delete from bench1 where field1 > 0") or die $DBI::errstr;
  1335. }
  1336. $end_time=new Benchmark;
  1337. print "Time for delete_all_many_keys ($count): " .
  1338.   timestr(timediff($end_time, $loop_time),"all") . "nn";
  1339. $sth = $dbh->do("drop table bench1" . $server->{'drop_attr'}) or die $DBI::errstr;
  1340. if ($opt_fast && defined($server->{vacuum}))
  1341. {
  1342.   $server->vacuum(1,$dbh);
  1343. }
  1344. #
  1345. # Test multi value inserts if the server supports it
  1346. #
  1347. if ($limits->{'insert_multi_value'})
  1348. {
  1349.   $query_size=$limits->{'query_size'}; # Same limit for all databases
  1350.   $sth = $dbh->do("drop table bench1" . $server->{'drop_attr'});
  1351.   do_many($dbh,$server->create("bench1",
  1352.        ["id int NOT NULL",
  1353. "id2 int NOT NULL",
  1354. "id3 int NOT NULL",
  1355. "dummy1 char(30)"],
  1356.        ["primary key (id,id2)",
  1357.        "index index_id3 (id3)"]));
  1358.   $loop_time=new Benchmark;
  1359.   if ($opt_lock_tables)
  1360.   {
  1361.     $sth = $dbh->do("LOCK TABLES bench1 write") || die $DBI::errstr;
  1362.   }
  1363.   if ($opt_fast && $server->{transactions})
  1364.   {
  1365.     $dbh->{AutoCommit} = 0;
  1366.   }
  1367.   print "Inserting $opt_loop_count rows with multiple valuesn";
  1368.   $query="insert into bench1 values ";
  1369.   $res=$query;
  1370.   for ($i=0 ; $i < $opt_loop_count ; $i++)
  1371.   {
  1372.     my $tmp= "($i,$i,$i,'EFGHIJKLM'),";
  1373.     if (length($i)+length($res) < $query_size)
  1374.     {
  1375.       $res.= $tmp;
  1376.     }
  1377.     else
  1378.     {
  1379.       do_query($dbh,substr($res,0,length($res)-1));
  1380.       $res=$query .$tmp;
  1381.     }
  1382.   }
  1383.   do_query($dbh,substr($res,0,length($res)-1));
  1384.   if ($opt_lock_tables)
  1385.   {
  1386.     $sth = $dbh->do("UNLOCK TABLES ") || die $DBI::errstr;
  1387.   }
  1388.   if ($opt_fast && $server->{transactions})
  1389.   {
  1390.     $dbh->commit;
  1391.     $dbh->{AutoCommit} = 1;
  1392.   }
  1393.   $end_time=new Benchmark;
  1394.   print "Time for multiple_value_insert (" . ($opt_loop_count) . "): " .
  1395.     timestr(timediff($end_time, $loop_time),"all") . "nn";
  1396.   if ($opt_lock_tables)
  1397.   {
  1398.     $sth = $dbh->do("UNLOCK TABLES ") || die $DBI::errstr;
  1399.   }
  1400.   # A big table may take a while to drop
  1401.   $loop_time=new Benchmark;
  1402.   $sth = $dbh->do("drop table bench1" . $server->{'drop_attr'}) or die $DBI::errstr;
  1403.   $end_time=new Benchmark;
  1404.   print "Time for drop table(1): " .
  1405.     timestr(timediff($end_time, $loop_time),"all") . "nn";
  1406. }
  1407. ####
  1408. #### End of benchmark
  1409. ####
  1410. $dbh->disconnect; # close connection
  1411. end_benchmark($start_time);
  1412. ###
  1413. ### Some help functions
  1414. ###
  1415. # Do some sample selects on direct key
  1416. # First select finds a row, the second one doesn't find.
  1417. sub check_select_key
  1418. {
  1419.   my ($sel_columns,$column,$check)= @_;
  1420.   my ($loop_time,$end_time,$i,$tmp_var,$tmp,$count,$row_count,$estimated);
  1421.   $estimated=0;
  1422.   $loop_time=new Benchmark;
  1423.   $count=0;
  1424.   for ($i=1 ; $i <= $opt_read_key_loop_count; $i++)
  1425.   {
  1426.     $count+=2;
  1427.     $tmpvar^= ((($tmpvar + 63) + $i)*3 % $opt_loop_count);
  1428.     $tmp=$tmpvar % ($total_rows);
  1429.     fetch_all_rows($dbh,"select $sel_columns from bench1 where $column=$tmp")
  1430.       or die $DBI::errstr;
  1431.     $tmp+=$total_rows;
  1432.     defined($row_count=fetch_all_rows($dbh,"select $sel_columns from bench1 where $column=$tmp")) or die $DBI::errstr;
  1433.     die "Found $row_count rows on impossible id: $tmpn" if ($row_count);
  1434.     $end_time=new Benchmark;
  1435.     last if ($estimated=predict_query_time($loop_time,$end_time,$count,$i,
  1436.    $opt_loop_count));
  1437.   }
  1438.   if ($estimated)
  1439.   { print "Estimated time"; }
  1440.   else
  1441.   { print "Time"; }
  1442.   print " for $check ($count): " .
  1443.     timestr(timediff($end_time, $loop_time),"all") . "n";
  1444. }
  1445. # Same as above, but select on 2 columns
  1446. sub check_select_key2
  1447. {
  1448.   my ($sel_columns,$column,$column2,$check)= @_;
  1449.   my ($loop_time,$end_time,$i,$tmp_var,$tmp,$count,$row_count,$estimated);
  1450.   $estimated=0;
  1451.   $loop_time=new Benchmark;
  1452.   $count=0;
  1453.   for ($i=1 ; $i <= $opt_read_key_loop_count; $i++)
  1454.   {
  1455.     $count+=2;
  1456.     $tmpvar^= ((($tmpvar + 63) + $i)*3 % $opt_loop_count);
  1457.     $tmp=$tmpvar % ($total_rows);
  1458.     fetch_all_rows($dbh,"select $sel_columns from bench1 where $column=$tmp and $column2=$tmp")
  1459.       or die $DBI::errstr;
  1460.     $tmp+=$total_rows;
  1461.     defined($row_count=fetch_all_rows($dbh,"select $sel_columns from bench1 where $column=$tmp and $column2=$tmp")) or die $DBI::errstr;
  1462.     die "Found $row_count rows on impossible id: $tmpn" if ($row_count);
  1463.     $end_time=new Benchmark;
  1464.     last if ($estimated=predict_query_time($loop_time,$end_time,$count,$i,
  1465.    $opt_loop_count));
  1466.   }
  1467.   if ($estimated)
  1468.   { print "Estimated time"; }
  1469.   else
  1470.   { print "Time"; }
  1471.   print " for $check ($count): " .
  1472.     timestr(timediff($end_time, $loop_time),"all") . "n";
  1473. }
  1474. #
  1475. # Search using some very simple queries
  1476. #
  1477. sub check_select_range
  1478. {
  1479.   my ($column,$check)= @_;
  1480.   my ($loop_time,$end_time,$i,$tmp_var,$tmp,$query,$rows,$estimated);
  1481.   $estimated=0;
  1482.   $loop_time=new Benchmark;
  1483.   $found=$count=0;
  1484.   for ($test=1 ; $test <= $range_loop_count; $test++)
  1485.   {
  1486.     $count+=$#Q+1;
  1487.     for ($i=0 ; $i < $#Q ; $i+=2)
  1488.     {
  1489.       $query=$Q[$i];
  1490.       $rows=$Q[$i+1];
  1491.       $query =~ s/!id!/$column/g;
  1492.       if (($row_count=fetch_all_rows($dbh,$query)) != $rows)
  1493.       {
  1494. if ($row_count == undef())
  1495. {
  1496.   die "Got error: $DBI::errstr when executing $queryn";
  1497. }
  1498. die "'$query' returned wrong number of rows: $row_count instead of $rowsn";
  1499.       }
  1500.       $found+=$row_count;
  1501.     }
  1502.     $end_time=new Benchmark;
  1503.     last if ($estimated=predict_query_time($loop_time,$end_time,$count,$test,
  1504.    $range_loop_count));
  1505.   }
  1506.   if ($estimated)
  1507.   { print "Estimated time"; }
  1508.   else
  1509.   { print "Time"; }
  1510.   print " for $check ($count:$found): " .
  1511.     timestr(timediff($end_time, $loop_time),"all") . "n";
  1512. }
  1513. #
  1514. # SELECT * from bench where col=x or col=x or col=x ...
  1515. sub check_or_range
  1516. {
  1517.   my ($column,$check)= @_;
  1518.   my ($loop_time,$end_time,$i,$tmp_var,$tmp,$columns,$estimated,$found,
  1519.       $or_part,$count,$loop_count);
  1520.   $columns=min($limits->{'max_columns'},50,($limits->{'query_size'}-50)/13);
  1521.   $columns=$columns- ($columns % 4); # Make Divisible by 4
  1522.   $estimated=0;
  1523.   $loop_time=new Benchmark;
  1524.   $found=0;
  1525.   # The number of tests must be divisible by the following
  1526.   $tmp= $limits->{'func_extra_in_num'} ? 15 : 10; 
  1527.   # We need to calculate the exact number of test to make 'Estimated' right
  1528.   $loop_count=$range_loop_count*10+$tmp-1;
  1529.   $loop_count=$loop_count- ($loop_count % $tmp);
  1530.   
  1531.   for ($count=0 ; $count < $loop_count ; )
  1532.   {
  1533.     for ($rowcnt=0; $rowcnt <= $columns; $rowcnt+= $columns/4)
  1534.     {
  1535.       my $query="select * from bench1 where ";
  1536.       my $or_part= "$column = 1";
  1537.       $count+=2;
  1538.       for ($i=1 ; $i < $rowcnt ; $i++)
  1539.       {
  1540. $tmpvar^= ((($tmpvar + 63) + $i)*3 % $opt_loop_count);
  1541. $tmp=$tmpvar % ($opt_loop_count*4);
  1542. $or_part.=" or $column=$tmp";
  1543.       }
  1544.       print $query . $or_part . "n" if ($opt_debug);
  1545.       ($rows=fetch_all_rows($dbh,$query . $or_part)) or die $DBI::errstr;
  1546.       $found+=$rows;
  1547.       if ($limits->{'func_extra_in_num'})
  1548.       {
  1549. my $in_part=$or_part; # Same query, but use 'func_extra_in_num' instead.
  1550. $in_part=~ s/ = / IN (/;
  1551. $in_part=~ s/ or $column=/,/g;
  1552. $in_part.= ")";
  1553. fetch_all_rows($dbh,$query . $in_part) or die $DBI::errstr;
  1554. $count++;
  1555.       }
  1556.       # Do it a little harder by setting a extra range
  1557.       defined(($rows=fetch_all_rows($dbh,"$query($or_part) and $column < 10"))) or die $DBI::errstr;
  1558.       $found+=$rows;
  1559.     }
  1560.     $end_time=new Benchmark;
  1561.     last if ($estimated=predict_query_time($loop_time,$end_time,$count,$count,
  1562.    $loop_count));
  1563.   }
  1564.   if ($estimated)
  1565.   { print "Estimated time"; }
  1566.   else
  1567.   { print "Time"; }
  1568.   print " for $check ($count:$found): " .
  1569.     timestr(timediff($end_time, $loop_time),"all") . "n";
  1570. }
  1571. #
  1572. # General test of SELECT ... WHERE id in(value-list)
  1573. #
  1574. sub test_where_in
  1575. {
  1576.   my ($t1,$t2,$id,$from,$to)= @_;
  1577.   return if ($from >= $to);
  1578.   $query="SELECT $t1.* FROM $t1 WHERE $id IN (";
  1579.   for ($i=1 ; $i <= $to ; $i++)
  1580.   {
  1581.     $query.="$i,";
  1582.   }
  1583.   $query=substr($query,0,length($query)-1) . ")";
  1584.   # Fill join table to have the same id's as 'query'
  1585.   for ($i= $from ; $i <= $to ; $i++)
  1586.   {
  1587.     $dbh->do("insert into $t2 values($i)") or die $DBI::errstr;
  1588.   }
  1589.   if ($opt_fast && defined($server->{vacuum}))
  1590.   {
  1591.     $server->vacuum(1,$dbh,"bench1");
  1592.   }
  1593.   time_fetch_all_rows("Testing SELECT ... WHERE id in ($to values)",
  1594.       "select_in", $query, $dbh,
  1595.       $range_loop_count);
  1596.   time_fetch_all_rows(undef, "select_join_in",
  1597.       "SELECT $t1.* FROM $t2 left outer join $t1 on ($t1.$id=$t2.$id)",
  1598.        $dbh, $range_loop_count);
  1599. }