高效的sql内连接查询

时间:2015-03-11 08:51:36

标签: mysql optimization inner-join

我有6个表,ABCDEF。这是一个星型模式,其中F表是事实表,而ABCDE是维度表

我的查询现在:

SELECT * FROM F INNER JOIN A ON A.id = F.id
                INNER JOIN B ON B.id = F.id
                INNER JOIN C ON C.id = F.id
                INNER JOIN D ON D.id = F.id
                INNER JOIN E ON E.id = F.id
WHERE C.cellName = 'XOR' AND A.lib = 'd04'

我已经将cellName编入索引,但是这种类型的查询非常慢,因为它查看F表中的所有行,并且在使用EXPLAIN时没有使用索引

在搜索C.id之前,是否有更好的方法让查询通过过滤A.idC.cellName来获取A.libF表?

  CELLPROPERTYFACT | CREATE TABLE `CELLPROPERTYFACT` (
  `libraryID` int(11) DEFAULT NULL,
  `cellID` int(11) DEFAULT NULL,
  `pinID` int(11) DEFAULT NULL,
  `toP` varchar(10) DEFAULT NULL,
  `whend` varchar(50) DEFAULT NULL,
  `cellRiseID` int(11) DEFAULT NULL,
  `cellFallID` int(11) DEFAULT NULL,
  `risePowerID` int(11) DEFAULT NULL,
  `fallPowerID` int(11) DEFAULT NULL,
  KEY `libraryID` (`libraryID`),
  KEY `cellID` (`cellID`),
  KEY `pinID` (`pinID`),
  KEY `cellRiseID` (`cellRiseID`),
  KEY `cellFallID` (`cellFallID`),
  KEY `risePowerID` (`risePowerID`),
  KEY `fallPowerID` (`fallPowerID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |


  CELL  | CREATE TABLE `CELL` (
  `cellID` int(11) NOT NULL AUTO_INCREMENT,
  `cellName` varchar(20) DEFAULT NULL,
  `area` float DEFAULT NULL,
  `leakage` float DEFAULT NULL,
  `frequency` varchar(50) DEFAULT NULL,
  `descp` varchar(50) DEFAULT NULL,
  `libID` int(11) DEFAULT NULL,
  PRIMARY KEY (`cellID`),
  KEY `A` (`cellName`)
) ENGINE=MyISAM AUTO_INCREMENT=150366 DEFAULT CHARSET=latin1 |


LIBRARY | CREATE TABLE `LIBRARY` (
  `libraryID` int(11) NOT NULL AUTO_INCREMENT,
  `opcond` varchar(100) DEFAULT NULL,
  `file` varchar(100) DEFAULT NULL,
  `workWeek` varchar(15) DEFAULT NULL,
  PRIMARY KEY (`libraryID`)

) ENGINE=MyISAM AUTO_INCREMENT=382 DEFAULT CHARSET=latin1 |


DIM_CELLRISE | CREATE TABLE `DIM_CELLRISE` (
  `cellRiseID` int(11) NOT NULL AUTO_INCREMENT,
  `value` float DEFAULT NULL,
  `whend` varchar(50) DEFAULT NULL,
  `begin_template_ptr` int(11) DEFAULT NULL,
  `end_template_ptr` int(11) DEFAULT NULL,
  `begin_template_line` int(11) DEFAULT NULL,
  `end_template_line` int(11) DEFAULT NULL,
  PRIMARY KEY (`cellRiseID`)
) ENGINE=MyISAM AUTO_INCREMENT=1073635 DEFAULT CHARSET=latin1 |


DIM_CELLFALL | CREATE TABLE `DIM_CELLFALL` (
  `cellFallID` int(11) NOT NULL AUTO_INCREMENT,
  `value` float DEFAULT NULL,
  `whend` varchar(50) DEFAULT NULL,
  `begin_template_ptr` int(11) DEFAULT NULL,
  `end_template_ptr` int(11) DEFAULT NULL,
  `begin_template_line` int(11) DEFAULT NULL,
  `end_template_line` int(11) DEFAULT NULL,
  PRIMARY KEY (`cellFallID`)
) ENGINE=MyISAM AUTO_INCREMENT=1162150 DEFAULT CHARSET=latin1 |

3 个答案:

答案 0 :(得分:0)

A.lib需要索引或C.cellName。 (两人都获得了帮助,并且没有受到伤害。

这不是一个"星型模式&#34 ;;这是6个垂直分区。我怀疑你过多地简化了SELECT。

请向我们展示所有6个表的SHOW CREATE TABLE。

答案 1 :(得分:0)

扫描F表很可能实际上是此查询的最有效访问路径。如果要使用表中超过25%的行,则扫描速度快于索引访问。

答案 2 :(得分:0)

尝试使用连接条件

SELECT * FROM F INNER JOIN A ON F.id = A.id AND A.lib = 'd04'
                INNER JOIN B ON F.id = B.id
                INNER JOIN C ON F.id = C.id AND C.cellName = 'XOR'
                INNER JOIN D ON F.id = D.id
                INNER JOIN E ON F.id = E.id