home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / mysql / mysql-3.23.28g-win.exe / DATA1.CAB / Benchmark_Files / bench / test-insert < prev    next >
Text File  |  2000-11-22  |  44KB  |  1,565 lines

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