2011-05-06 192 views
0

我在mysql中的两个表:Mysql的连接查询优化

Results Table : 1046928 rows. 
Nodes Table : 50 rows. 

我用下面的查询和查询的执行连接这两个表是非常非常慢。

select res.TIndex, res.PNumber, res.Sender, res.Receiver, 
sta.Nickname, rta.Nickname from ((Results res join 
Nodes sta) join Nodes rta) where ((res.sender_h=sta.name) and 
(res.receiver_h=rta.name)); 

请帮我优化此查询。现在,如果我想拉动前5排,大约需要5-6分钟。谢谢。

CREATE TABLE `nodes1` (
    `NodeID` int(11) NOT NULL, 
    `Name` varchar(254) NOT NULL, 
    `Nickname` varchar(254) NOT NULL, 
    PRIMARY KEY (`NodeID`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 

CREATE TABLE `Results1` (
    `TIndex` int(11) NOT NULL, 
    `PNumber` int(11) NOT NULL, 
    `Sender` varchar(254) NOT NULL, 
    `Receiver` varchar(254) NOT NULL, 
    `PTime` datetime NOT NULL, 
    PRIMARY KEY (`TIndex`,`PNumber`), 
    KEY `PERIOD_TIME_IDX` (`PTime`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 
+0

发布2个表的SHOW CREATE TABLE输出 – 2011-05-06 00:47:22

+0

该查询甚至不是有效的。 – 2011-05-06 00:51:42

+0

你只是指拼写错误还是有更大的想法?我没有看到任何逻辑错误的东西,只是'tra' vs'rta' – 2011-05-06 00:54:29

回答

4
SELECT res.TIndex , 
     res.PNumber , 
     res.Sender , 
     res.Receiver , 
     sta.Nickname , 
     rta.Nickname 
FROM Results AS res 
     INNER JOIN Nodes AS sta ON res.sender_h = sta.name 
     INNER JOIN Nodes AS rta ON res.receiver_h = rta.NAME 
  1. 上创建结果的索引 (sender_h)
  2. 上创建结果的索引(receiver_h)
  3. 上创建节点(名)的索引
+0

+1改变where where条款加入条件并添加这些索引应该有很大的不同。即时通讯猜测,与完整的联接和where子句一个巨大的笛卡尔产品在修剪之前被中间创建。任何人都可以验证这个或它是否得到优化? – 2011-05-06 01:08:33

+0

据我所知,在JOIN之间没有任何真正的性能增益。我只是更喜欢JOIN语法,因为它使含义非常清晰。例如,这些是我的表格连接,这些是我的过滤器。所有的性能提升都是通过添加索引来实现的。您可以重试您的旧查询,并且它应该同样快速地运行。 – 2011-05-06 01:17:54

1

加入节点的name而不是NodeId(主键)看起来不太好。

也许你应该为外键senderreceiverResults表,而不是name添加外键约束被存储NodeId过一个好主意。别的不说,这可能导致索引会自动根据你的配置

如果这个改变是困难的,你应该强制唯一性上nodename

如果以这种方式来改变表定义的最起码,改变你的查询约翰的建议,并添加索引,它应该运行得更好,并有更多的可读性/更好的形式。