home *** CD-ROM | disk | FTP | other *** search
/ PC World 2003 July & August / PCWorld_2003-07-08_cd.bin / Software / Vyzkuste / mysql / data1.cab / Development / bench / test-insert < prev    next >
Text File  |  2003-05-17  |  49KB  |  1,750 lines

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