MySQL – Optimize MySQL Database Performance

innodbMySQLoptimizationperformance

I have a database with some relatively small tables and one big table with about 10 million rows (11 columns) that I would like to optimize its performance. The table looks like this:

  • Id: (int 11, primary key)
  • Codigo: (longtext)
  • Act_mas: (double)
  • Act_menos: (double)
  • Ind_mas: (double)
  • Ind_menos: (double)
  • Cap_mas: (double)
  • Cap_menos: (double)
  • Mensaje: (longtext)
  • Fecha: (datetime)
  • SuministrosId (int 11, this is a foreign key of a table with 62 rows, 21 columns that has another 2 foreign key, one with 44 rows and 11 columns and the other with 2 rows and 2 columns)

I guess I could change the datatype of Codigo and Mensaje to something like VARCHAR(10), since normally the value has less than 10 characters and probably LONGTEXT is an overkill.

I could also change column datatype, from Act_mas to Cap_menos, to INT, since all the values should be smaller than 1.000.000 (at the moment the biggest value is 795.600, and it's very strange to have such a value).

The database and the table is using 'InnoDB' engine.

Actually a query like SELECT * FROM table WHERE SuministrosId = 4 and Fecha >= "2015-01-01" takes about 3-5 seconds to load. Maybe its not too much but I think it could be lot less.
I tried to change the datatype of some columns but it was terribly slow and I had to stop it, should I give another try? Also I added an index to SuministrosId but it seemed to be the same.

If other data is needed feel free to ask. Thank you in advance! (And sorry for my English :c)

EDIT

Computer info:

CPU: Intel(R) Xeon(R) CPU E5-2609 v4 @ 1.70 GHz

RAM: 32 GB

OS: Windows Server 2012 R2 Standard

MySQL Version: 5.7.11

The database is used by an external java program that typically uses queries like the described above: SELECT * FROM consumos WHERE SuministrosId = 4 and Fecha >= "2015-01-01", this is the most used query since it's the "core" for the job done here. Some other queries are used to list clients like: SELECT * FROM clientes, or SELECT * FROM suministros. But those tables are really small and they are not a problem.

SHOW CREATE TABLE for the big one:

CREATE TABLE `consumos` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`Codigo` longtext NOT NULL,
`Act_mas` double NOT NULL,
`Act_menos` double NOT NULL,
`Ind_mas` double NOT NULL,
`Ind_menos` double NOT NULL,
`Cap_mas` double NOT NULL,
`Cap_menos` double NOT NULL,
`Mensaje` longtext NOT NULL,
`Fecha` datetime NOT NULL,
`SuministrosId` int(11) NOT NULL,
PRIMARY KEY (`Id`),
KEY `IX_FK_Contadorsuministrosset` (`SuministrosId`),
KEY `Fecha` (`Fecha`),
CONSTRAINT `FK_Contadorsuministrosset` FOREIGN KEY (`SuministrosId`) REFERENCES `suministros` (`Id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=13002432 DEFAULT CHARSET=latin1

Query explain: enter image description here

Profile:
enter image description here

Best Answer

That one query can be optimized with a composite index: INDEX(SuministrosId, Fecha). Let's see some more. (Meanwhile, that pie chart is useless, it rarely says anything other than "sending data", and that gives no clues.)

Also, it may help to set innodb_buffer_pool_size to about 20G assuming you are using 64-bit OS and MySQL.