更好的方法来做这个子查询

时间:2013-10-09 23:05:42

标签: php mysql sql performance

假设我有这个问题:

<?
     $qi = $db->prepare('SELECT one.id, one.Value, two.Name, three.nfid, temp.Name AS Alias
           FROM one
           INNER JOIN two ON one.fid = two.id
           LEFT OUTER JOIN three ON two.fid = three.fid
           LEFT OUTER JOIN (SELECT id,Name FROM two) AS temp ON three.nfid = temp.id
           WHERE one.rid = ?
           ORDER BY one.id ASC');
      $qi->execute( array( $id ) );
?>

表之间的连接是:

一个包含多个包含字段one.Valueone.ridone.fid的行。

fid是与表两个的连接,其中包含two.Name项(one.fid = two.id)。

但有时该项目是另一项目的别名,这就是为什么表格存在的原因。它包含字段three.fidthree.newfid,其中three.newfid = two.id(但另一个项目包含另一个two.Name

该查询应该从具有某个one.rid一个获取所有行,并获取one.Valuetwo.Name并且如果有three.fid对于此one.fid,请two.Name获取three.newfid并将其命名为Alias。

有没有办法改进此查询或以其他方式解决问题?也许重塑数据库的布局?目前它很慢。这里的例子已经简化,使其更加通用。

谢谢。

1 个答案:

答案 0 :(得分:1)

括号中的子查询强制MYSQL忽略其索引,这需要很长时间。最好直接加入两个作为临时。只要你总是放两个。[field]和temp。[field],就会告诉他们分开。

  SELECT one.id, one.Value, two.Name, three.nfid, temp.Name AS Alias
  FROM one
  INNER JOIN two ON one.fid = two.id
  LEFT OUTER JOIN three ON two.fid = three.fid
  LEFT OUTER JOIN two AS temp ON three.nfid = temp.id
  WHERE one.rid = ?
  ORDER BY one.id ASC