I have a lot of tables, and not all of them are filled equally. Inserts to tables that have a lot of entries(see the count below), take a long time (about .06 secs on the average in mysql, over 0.09-0.1 in DBI), for example
mysql> INSERT INTO T1 VALUES ('3CCF571C1A881188010403000002','072','7269','','','','' ,'','',3103,1,24,'2002-09- 01','05:46:52',0.99,13.7560,24.0480,0.0710,190.839,16,0, 0,1,0,0,0,0,0,0,0,0,0,3,4,0,0,0,0,0,0,10,0,'1',1,'0',0,1 ,0,'200205010250_ampsc1','AMP',4,'-12015927269-1-95- 3855206',1,0); Query OK, 1 row affected (0.06 sec) inserts into tables like T2 which have few elements take a much shorter time: mysql> INSERT INTO T2 VALUES ('3CCF571C1A881188010403000002','072','7269','','','','' ,'','',3103,1,24,'2002-09- 01','05:46:52',0.99,13.7560,24.0480,0.0710,190.839,16,0, 0,1,0,0,0,0,0,0,0,0,0,3,4,0,0,0,0,0,0,10,0,'1',1,'0',0,1 ,0,'200205010250_ampsc1','AMP',4,'-12015927269-1-95- 3855206',1,0); Query OK, 1 row affected (0.00 sec) mysql> SELECT COUNT(*) FROM T2; +----------+ | COUNT(*) | +----------+ | 509 | +----------+ 1 row in set (0.00 sec) mysql> SELECT COUNT(*) FROM T1; +----------+ | COUNT(*) | +----------+ | 782910 | +----------+ 1 row in set (7.43 sec) Of course DELETES are similar(actually much worse with a where), but deletes are not an issue here mysql> DELETE FROM T1 WHERE date ='2002-09-01'; Query OK, 1 row affected (40.19 sec) mysql> DELETE FROM T2 WHERE date ='2002-09-01'; Query OK, 1 row affected (0.24 sec) I presume the problem is that in the table definitions I have a couple of unique constraints and the INSERT time difference is due to mysql checking all entries in the table for a unique violation, hence the insert would be slow: CREATE TABLE T1 ( corrno varchar(43) default NULL, a varchar(30) default NULL, b varchar(30) default NULL, c varchar(30) default NULL, oc varchar(30) default NULL, red varchar(30) default NULL, sanum varchar(30) default NULL, sbnum varchar(30) default NULL, tnum varchar(30) default NULL, o int(5) default NULL, d int(5) default NULL, cic int(6) default NULL, date date default NULL, start_time time default NULL, value decimal(30,2) default NULL, iamtoacm decimal(7,4) default NULL, iamtoans decimal(7,4) default NULL, reltorlc decimal(7,4) default NULL, duration decimal(12,3) default NULL, rcv int(3) default NULL, rcvabn int(1) default '0', loc int(3) default NULL, reldir int(1) default NULL, secode int(3) default NULL, trans int(3) default NULL, tc int(3) default NULL, rsp 0 int(3) default NULL, ccq int(5) default NULL, ccr int(3) default NULL, ccc int(3) default NULL, ccp int(3) default NULL, ccsan int(3) default NULL, nata int(2) default NULL, natb int(2) default NULL, natc int(2) default NULL, natocn int(2) default NULL, natredir int(2) default NULL, natsccpa int(2) default NULL, natsccpbint(2) default NULL, nattrue int(2) default NULL, acat int(2) default NULL, bcat int(1) default NULL, upi char(1) default NULL, upp int(3) default NULL, acind char(1) default NULL, inter int(1) default NULL, ech int(1) default NULL, length int(3) default '0', file varchar(30) default NULL, link varchar(8) default NULL, fileind int(11) default NULL, unicor varchar(100) NOT NULL default '', stp int(1) default '0', alarm int(1) default '0', UNIQUE KEY unicor (unicor), UNIQUE KEY corrno (corrno) ) TYPE=InnoDB; The question is what can be done about this? I guess getting rid of the unique constraints would help, but then I would be getting some unwanted duplicates. I should add that currently I need to do about 100,000 inserts/10 minutes and the system is too slow for this as it is, while it used to be very fast. So, I am looking fro what can be done to avoid performance degradation as the tables fill. The server is a dual PIII x1000, 2GB RAM Linux 2.4.18 machine but the inserts are done from a client(a 1000 PIII , 1GB RAM Linux machine). Below is /etc/my.cnf # Example mysql config file for very large systems. > # > # This is for large system with memory of 1G-2G where > the system runs mainly > # MySQL. > # > # You can copy this file to > # /etc/mf.cnf to set global options, > # mysql-data-dir/my.cnf to set server-specific options > (in this > # installation this directory is /var/lib/mysql) or > # ~/.my.cnf to set user-specific options. > # > # One can in this file use all long options that the > program supports. > # If you want to know which options a program support, > run the program > # with --help option. > > # The following options will be passed to all MySQL > clients > [client] > #password = your_password > port = 3306 > socket = /var/lib/mysql/mysql.sock > > # Here follows entries for some specific programs > > # The MySQL server > [mysqld] > port = 3306 > socket = /var/lib/mysql/mysql.sock > skip-locking > set-variable = key_buffer_size=500M > set-variable = key_buffer=100M > set-variable = max_allowed_packet=1M > set-variable = table_cache=512 > set-variable = max_connections=10 > set-variable = tmp_table_size=400M > set-variable = sort_buffer=2M > set-variable = record_buffer=2M > set-variable = thread_cache=8 > set-variable = thread_concurrency=4 # Try number of > CPU's*2 > #set-variable = myisam_sort_buffer_size=64M > set-variable = myisam_sort_buffer_size=4M > innodb_data_home_dir= > #and then use absolute file paths > #innodb_data_file_path=ibdata1:2000M;ibdata2:2000M;ibdat > a3:2000M;ibdata4:2000M;ibdata5:2000M;ibdata6:2000M;ibdat > a7:2000M;ibdata8:2000M > innodb_data_file_path=/var/lib/mysql/ibdata1:2000M;/var/ > lib/mysql/ibdata2:2000M;/var/lib/mysql/ibdata3:2000M;/va > r/lib/mysql/ibdata4:2000M;/var/lib/mysql/ibdata5:2000M;/ > var/lib/mysql/ibdata6:2000M;/var/lib/mysql/ibdata7:2000M > ;/var/lib/mysql/ibdata8:2000M;/usr/ibdata/ibdata9:2000 M; > /usr/ibdata/ibdata10:2000M;/usr/ibdata/ibdata11:2000M; /u > sr/ibdata/ibdata12:2000M;/ibdata/ibdata13:2000M;/ibdata/ > ibdata14:2000M;/ibdata/ibdata15:2000M;/var/lib/mysql/ibd > ata16:2000M;/var/lib/mysql/ibdata17:2000M;/var/lib/mysql > /ibdata18:2000M;/var/lib/mysql/ibdata19:2000M;/var/lib /m > ysql/ibdata20:2000M;/var/lib/mysql/ibdata21:2000M > #;/usr/ibdata/ibdata9:2000M;/usr/ibdata/ibdata10:2000M > ## Comment next line if you do not need recovery(the > hostname-bin.xxx files) > #log-bin > ## > server-id = 1 > #set-variable = open-files-limit=8192 #ulimit is > 1024,hard 8192 > set-variable = innodb_buffer_pool_size=1100M > # so that innodb_buffer_pool > size+key_buffer+max_connections* > (sort_buffer+record_buffer+2M)=1100+100+10*(2+2+2) > =1260<2000M=RAM > set-variable = innodb_additional_mem_pool_size=700M > set-variable = innodb_log_file_size=1000M > set-variable = innodb_log_buffer_size=20M > # helps for large transactions > # Uncomment the following if you are using BDB tables > #set-variable = bdb_cache_size=384M > #set-variable = bdb_max_lock=100000 > > # Point the following paths to different dedicated disks > #tmpdir = /tmp/ > #log-update = /path-to-dedicated-directory/hostname > > [mysqldump] > quick > set-variable = max_allowed_packet=256M > > [mysql] > no-auto-rehash > #safe-updates # Remove the comment character if you > are not familiar with SQL > > [isamchk] > set-variable = key_buffer=256M > set-variable = sort_buffer=256M > set-variable = read_buffer=2M > set-variable = write_buffer=2M > > [myisamchk] > #set-variable = key_buffer=256M > #set-variable = sort_buffer=256M > #set-variable = read_buffer=2M > #set-variable = write_buffer=2M > set-variable = key_buffer=25M > set-variable = sort_buffer=25M > set-variable = read_buffer=2M > set-variable = write_buffer=2M > > [mysqlhotcopy] > interactive-timeout > ------------------------------------------------------ ===================== Inserts are done via DBI; the relevant routine is below: Basically three things are done: 1)an insert via $sth in the 'storage' tables 2) an insert into a summary table, i.e. we check if summary data for one of the values in the entry exists (I think the fastes way is via a SELECT date from tablename WHERE date=$date LIMIT 1; rather via a count which needs to find all occurences If there is already an entry, we use an undate handle else an insert handle sub dumpknown_out{ my $tablname=shift;#table in which to insert,only used for diagnostics my $ansc=shift; #a variable to decide on what to compute #and insert my $dbh=shift; #needed for the commit; my $sth=shift; #statement handle for insert my $action1=shift; my $action2=shift; my $ndestact=shift; my $cntprep=shift; my $sthupdate=shift; my $sthsumins=shift; my $sthsumtst=shift; my $outincupdate=shift; my $outincins=shift; my $outinctst=shift; my $dest=shift; my $finaldest=shift; my $relpos=shift; my $locpos=shift; my $rmask=shift; #die "unknown $tablname\\n" unless ($tablname=~/CDR_OUTGOING_(.*)_\\d/); #my $dest=$1; my @values=(); my $redirectmark=0; #my $ansc=0; #$ansc=1 if $tablname=~/_1$/; $redirectmark=1 if($_[4]=~/\\w/ or $_[5]=~/\\w/);#$CB_OCN or CB_REDIRECTINGNUM my $count=0; my $destcnt=0; my $flag=0; foreach my $ii(@_){#foreach field unless( $rmask->[$count]){$ii=0 unless $ii;} push @values,$ii; $count++;} eval { $destcnt += $ndestact->execute($values[1],$dest); $sth->execute(@values) ; $cntprep->execute($values[1]);my $countq=$cntprep- >fetchrow_array(); unless($countq){ $action1->execute($values[1],1,$values[14],$values [18],$ansc,1,$values[53],$redirectmark) or die "could not execute action countq= $countq anum=$values[1] value= $values[14] dur= $values[18] ansc=$ansc alarm=$values[53] redirectmark=$redirectmark table=$tablname values=@values er is $DBI::errstr\\n"; }#unless countq else{ ##print "updating NDEST\\n"; #update Ndest if necessary $action2->execute($ansc,$values[14],$values [18],$destcnt,$values[53],$redirectmark,$values[1]) or die "could not execute action2 countq=$countq $DBI::errstr\\n"; }# $dbh->commit; };#end of eval if ($@) {$dbh->rollback; $flag=1; print main::DUMP "Transaction @values aborted because $@"; #keep temporarily # add other application on-error-clean-up code here } else{# initiate or update SUMMARY REPORT # does this date, hour, type, link exist? my $cnt=0; my $time=substr($values[13],0,2) .':00'; $sthsumtst->execute($values[49],'OUTGOING',$values [12],$time,$dest); #"SELECT COUNT(*) FROM SUMMARYDATA WHERE link=? AND type=? # AND date=? and time=? "); my @returned=(0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0); #132 0's unless ($ansc){ $returned[$relpos+55]=1 if $relpos=~/\\d/; #release cause $returned[$locpos+124]=1 if $locpos=~/\\d/; #location } # now find the location of the duartion interval else{ $outinctst->execute($dest, $values[49], $values[12]); #add to income if( $outinctst->fetchrow_array) { #update $outincupdate->execute($values[14], $dest, $values[49], $values[12]); }else{#initialize $outincins->execute($dest, $values[49], $values [12],1,$values[14] ); } my $dur=int($values[18] /10); if($dur <1){$dur=0;} #count negative durations as 0 $returned[27]= $values[18];# this is sumcount if($dur < 25){$returned[$dur]=$values[18]; $returned [$dur+28]=1;} elsif($dur >30){$returned[26]=$values[18]; $returned[54] =1;} else{#in 250-300 $returned[25]=$values[18]; $returned[53]=1;} }#else ansc=1 eval{#now for SUMMARY DATA my $iam1=1000 * $values[15]; my $iam2=1000 * $values [16]; if($sthsumtst->fetchrow_array){ #&reportstd(\\@returned ); $sthupdate->execute($ansc,$iam2,$iam1,@returned, $values[49],'OUTGOING',$values[12],$time ,$dest ); }else{#initialize $sthsumins->execute($values [49],'OUTGOING', $dest ,$finaldest, $values [12],$time,1,$ansc,$iam2,$iam1,@returned); } $dbh->commit;};#end of 2nd eval if ($@) {$dbh->rollback; print main::DUMP "SUMMARYDATA Transaction @values aborted because $@"; #keep temporarily # add other application on-error-clean-up code here } }#end of else initiate or update #if($flag){print main::DUMP "failed with @values\\n";} }#end of S/R dumpknown_out --------------------------------------------------------------------- Before posting, please check: http://www.mysql.com/manual.php (the manual) http://lists.mysql.com/ (the list archive) To request this thread, e-mail <[EMAIL PROTECTED]> To unsubscribe, e-mail <mysql-unsubscribe-##L=##[EMAIL PROTECTED]> Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php