mysql:从两者中选择最有效的查询

时间:2014-08-12 22:51:34

标签: mysql sql performance union

这两个mysql查询产生完全相同的结果,但查询A是一个简单的联合,它有where postType子句嵌入在单个查询中,而查询B具有相同的where子句应用于虚拟表的外部选择,这是单个查询结果的联合。我担心来自查询B的虚拟表sigma可能变得太大而没有充分的理由如果有很多行但是我有点困惑,因为如何按顺序工作查询A;是否也不必为了排序结果而制作虚拟表或类似的东西。所有这些都可能取决于工会的工作顺序如何?如果一个联盟的命令也在制作临时表;那么查询A几乎等同于资源中的查询B(与查询A相比,我们在系统中实现查询B要容易得多)?请以任何可能的方式提供指导/建议,谢谢

查询A

SELECT `t1`.*, `t2`.*
            FROM `t1` INNER JOIN `t2` ON
            `t1`.websiteID= `t2`.ownerID
            AND `t1`.authorID= `t2`.authorID
            AND `t1`.authorID=1559 AND `t1`.postType="simplePost"
UNION
            SELECT `t1`.*
             FROM `t1` where websiteID=1559 AND postType="simplePost" 
ORDER BY postID limit 0,50

查询B

Select * from (
SELECT `t1`.*,`t2`.*
            FROM `t1` INNER JOIN `t2` ON
             `t1`.websiteID= `t2`.ownerID
              AND `t1`.authorID= `t2`.authorID
            AND `t1`.authorID=1559
UNION
            SELECT `t1`.*
             FROM `t1` where websiteID=1559
)
As sigma  where postType="simplePost" ORDER BY postID limit 0,50

解析查询

id    type                table           type    possible_keys   keys            key_len ref         rows    Extra
1     PRIMARY             t2              ref     userID          userID          4       const       1       
1     PRIMARY             t1              ref     authorID        authorID        4       const       2       Usingwhere
2     UNION               t1              ref     websiteID       websiteID       4       const       9       Usingwhere
NULL  UNIONRESULT         <union1,2>      ALL     NULL            NULL            NULL    NULL        NULL    Usingfilesort

解析查询B

id    select_type     table       type    possible_keys   key         key_len     ref     rows    Extra
1     PRIMARY         <derived2>  ALL     NULL            NULL        NULL        NULL    10      Using where; Using filesort
2     DERIVED         t2          ref     userID          userID          4               1   
2     DERIVED         t1          ref     authorID        authorID        4               2       Using where
3     UNION           t1          ref     websiteID       websiteID       4               9   
NULL  UNION RESULT    <union2,3>  ALL     NULL            NULL        NULL        NULL    NULL

2 个答案:

答案 0 :(得分:2)

毫无疑问,版本1 - 将工会两边的条款分开 - 将更快。让我们来看看为什么版本 - 关于联合结果的where子句 - 更糟糕的是:

  • 数据量:联合结果中总会有更多行,因为返回的行的条件较少。这意味着更多的磁盘I / O(取决于索引),更多的临时存储来容纳行集,这意味着更多的处理时间
  • 重复扫描:当初始扫描期间可以处理时,必须再次扫描联合的整个结果以应用条件。这意味着双重处理行集,虽然可能在内存中,但仍然是额外的工作。
  • 索引不用于union结果的where子句。如果您对外键字段 postType有索引,则不会使用它

如果您想获得最高性能,请使用UNION ALL,它将行直接传递到结果中而没有开销,而不是UNION,这会删除重复项(通常通过排序)并且可能很昂贵根据您的评论是不必要的

定义这些索引并使用版本1以获得最佳性能:

create index t1_authorID_postType on t1(authorID, postType);
create index t1_websiteID_postType on t1(websiteID, postType);

答案 1 :(得分:0)

也许这可以代替:

SELECT
     `t1`.*
    ,`t2`.*
FROM `t1`
LEFT JOIN `t2` ON `t1`.websiteID = `t2`.ownerID
    AND `t1`.authorID = `t2`.authorID
    AND `t1`.authorID = 1559
WHERE ( `t1`.authorID = 1559 OR `t1`.websiteID = 1559 )
    AND `t1`.postType = 'simplePost'
ORDER BY postID limit 0 ,50