You join the indicators table to the instruments table, and the indicators.instrument_id column is not indexed.
You also join the instruments table to the stockdata table using the instruments.name and stockdata.name , both of which are of type CHAR . Joining using CHAR or VARCHAR usually significantly slower than joining using INT columns:
Using CHAR keys for connections, how much overhead?
To make matters worse, your CHAR columns have different sizes ( char(20) and char(10) respectively) and they are not indexed. It really complicates the work of MySQL! See How MySQL Uses Indexes for more information.
Ideally, you should change your table structure so that the join can be made using indexed INT fields. Something like that:
CREATE TABLE `instruments` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` char(20) DEFAULT NULL, `country` char(50) DEFAULT NULL, `newsquery` char(100) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB; CREATE TABLE `indicators` ( `id` int(11) NOT NULL AUTO_INCREMENT, `instrument_id` int(11) DEFAULT NULL, `date` date DEFAULT NULL, `sma_5` float(10,3) DEFAULT NULL, `sma_14` float(10,3) DEFAULT NULL, `ema_14` float(10,3) DEFAULT NULL, PRIMARY KEY (`id`), KEY `fk_instrument_indicators` (`instrument_id`), CONSTRAINT `fk_instrument_indicators` FOREIGN KEY (`instrument_id`) REFERENCES `instruments` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB; CREATE TABLE `stockdata` ( `id` int(11) NOT NULL AUTO_INCREMENT, `instrument_id` int(11) NOT NULL, `name` char(20) DEFAULT NULL, `date` date DEFAULT NULL, `open` float DEFAULT NULL, `high` float DEFAULT NULL, `low` float DEFAULT NULL, `close` float DEFAULT NULL, `volume` int(11) DEFAULT NULL, `adjclose` float DEFAULT NULL, PRIMARY KEY (`id`), KEY `fk_instrument_stockdata` (`instrument_id`), CONSTRAINT `fk_instrument_stockdata` FOREIGN KEY (`instrument_id`) REFERENCES `instruments` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB;
Then use the indexed fields in your connection:
SELECT indicators.date, instruments.name, indicators.sma_14, indicators.sma_5, stockdata.close FROM indicators INNER JOIN instruments ON (indicators.instrument_id=instruments.id) INNER JOIN stockdata ON (instruments.id=stockdata.instrument_id)
Using INT indexed columns, your joins will be much faster. Using InnoDB constraints can help ensure data integrity.
If there is a reason you should join the name column, make both sizes and index them.