Question

Hi I was hoping I could get some help on how to optimize my database so it doesn't take a year. I know that to speed it up I need to add indexes, but I'm not exactly sure on what I should be adding them on.

Heres the three tables in my database:

CREATE TABLE IF NOT EXISTS `journeyPattern2` (
  `journeyPatternId` int(11) NOT NULL AUTO_INCREMENT,
  `serviceId` int(11) NOT NULL,
  `direction` enum('inbound','outbound') NOT NULL,
  PRIMARY KEY (`journeyPatternId`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `journeyPatternTimingLink2` (
  `journeyPatternTimingLinkId` int(11) NOT NULL AUTO_INCREMENT,
  `journeyPatternId` int(11) NOT NULL,
  `from` varchar(15) NOT NULL,
  `to` varchar(15) NOT NULL,
  `direction` enum('inbound','outbound') NOT NULL,
  `runTime` varchar(15) NOT NULL,
  PRIMARY KEY (`journeyPatternTimingLinkId`),
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

CREATE TABLE IF NOT EXISTS `line` (
  `lineId` int(11) NOT NULL AUTO_INCREMENT,
  `serviceId` int(11) NOT NULL,
  `lineName` tinytext NOT NULL,
  PRIMARY KEY (`lineId`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

CREATE TABLE IF NOT EXISTS `service` (
  `serviceId` int(11) NOT NULL AUTO_INCREMENT,
  `serviceCode` varchar(50) NOT NULL,
  `registeredOperatorRef` varchar(50) NOT NULL,
  `origin` tinytext NOT NULL,
  `destination` tinytext NOT NULL,
  PRIMARY KEY (`serviceId`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

The table journeyPattern2 contains about 33000 rows, journeyPatternTimingLink2 contains around 13 million, and line and service around 70000.

The query I'm trying to optimize is the following

SELECT DISTINCT lineName,line.serviceId  FROM `journeyPatternTimingLink2` 
INNER JOIN journeyPattern2
ON journeyPattern2.journeyPatternId=journeyPatternTimingLink2.journeyPatternId
INNER JOIN line
ON journeyPattern2.serviceId = line.serviceId
WHERE `from` = '13006785E'

I've never really worked with tables of this size before so I'm not sure if I'm joining correctly in the first place. I've also uploaded a screenshot of me running EXPLAIN on the query from phpmyadmin, but I'm not exactly sure how to interpret the results so any help would be appreciated.

Thanks for your help.

Was it helpful?

Solution 2

You should add some indexes to these fields -

  • journeyPatternTimingLink2.journeyPatternId
  • journeyPattern2.serviceId
  • line.serviceId
  • journeyPatternTimingLink2.from

These are indexes used in JOIN-ON clauses and WHERE condition.

OTHER TIPS

You have to add some foreign keys or indexes on below mentioned columns:

  1. Add reference on jouurneyPatternId column from journeyPattern2 to journeyPatternTimingLink2
  2. Add reference on serviceId column from service to journeyPattern2
  3. Add reference on serviceId column from service to line

Add index on from column in journeyPatternTimingLink2 table.

The most important index should be on journeyPatternTimingLink2.from, because this is in your where clause and has two orders of magnitude more rows than all other tables combined.

You might also consider using InnoDB for all your tables. From Optimization Overview:

Note

In MySQL 5.5 and higher, InnoDB is the default storage engine for new tables. In practice, the advanced InnoDB performance features mean that InnoDB tables often outperform the simpler MyISAM tables, especially for a busy database.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top