MySQL联盟绩效问题

时间:2016-08-09 05:40:57

标签: mysql performance union

我有3个表(SuccessOrder,FailedOrder和PendingOrder)具有相同的列。每张表都有超过200万条记录。我需要组合这3个表中的所有数据,并按CreatedDate对它们进行排序,以显示在我的门户中。我正在使用UNION ALL来组合所有表的结果。

如果我执行每个子查询,则在1或2秒内得到结果。如果我执行整个查询(使用UNION ALL的3个子查询),则需要5分钟以上。

select * from (
select * from SuccessOrder
UNION ALL
select * from FailedOrder
UNION ALL
select * from PendingOrder
) t order by t.ID;

UNION ALL还有其他选择吗?

是否可以在没有UNION ALL的情况下从3个查询创建视图?

以下是从工作台测试的Individual和union查询。我没有看到 UNION ALL UNION ALL - ORDER BY

之间存在很大差异

首次质询

持续时间/获取时间 :2.182秒/ 1.513秒

SELECT  col1, col2, ...
    FROM  CompleteTxn ct
    left outer join  CompleteItem ci  ON (ct.Id = ci.TxnId)
    left outer join  ItemDispute id  ON (ct.Id = id.TxnId and  ci.Id = id.ItemId )
    left outer join  Merchant mc  ON (ct.MerchantId = mc.Id)
    left outer join  AdditionalTxnInfo addti  ON (ct.Id = addti.TxnId)
    where  (ct.PartitionKey>=55 AND  ct.PartitionKey<=56 )
      and  ( ct.TxnCompleteTime >= '2016-08-01 17:00:00'
        and  ct.TxnCompleteTime <= '2016-08-09 17:00:00'
           )
      and  ct.MnoId in (22,24,25,23,26,220,221,200,223,224,320, 400)
      and  ct.Status in (1,2,3,4,5);

第二次查询

持续时间/获取时间 :0.279秒/ 0.861秒

SELECT  col1, col2, ...
    FROM  FailedOrder ct
    left outer join  FailedItem ci  ON (ct.Id = ci.TxnId)
    left outer join  ItemDispute id  ON (ct.Id = id.TxnId and  ci.Id = id.ItemId )
    left outer join  Merchant mc  ON (ct.MerchantId = mc.Id)
    left outer join  AdditionalTxnInfo addti  ON (ct.Id = addti.TxnId)
    where  (ct.PartitionKey>=55 AND  ct.PartitionKey<=56 )
      and  ( ct.TxnCompleteTime >= '2016-08-01 17:00:00'
        and  ct.TxnCompleteTime <= '2016-08-09 17:00:00'
           )
      and  ct.MnoId in (22,24,25,23,26,220,221,200,223,224,320, 400);

通过

联合所有订单

持续时间/获取时间 :104.802秒/ 0.00027秒

select  *
    FROM  
    (
        SELECT  col1, col2, ...
            FROM  FailedOrder ct
            left outer join  FailedItem ci  ON (ct.Id = ci.TxnId)
            left outer join  ItemDispute id  ON (ct.Id = id.TxnId
                      and  ci.Id = id.ItemId 
                          )
            left outer join  Merchant mc  ON (ct.MerchantId = mc.Id)
            left outer join  AdditionalTxnInfo addti  ON (ct.Id = addti.TxnId)
    where  (ct.PartitionKey>=55 AND  ct.PartitionKey<=56 )
      and  ( ct.TxnCompleteTime >= '2016-08-01 17:00:00'
        and  ct.TxnCompleteTime <= '2016-08-09 17:00:00'
           )
      and  ct.MnoId in (22,24,25,23,26,220,221,200,223,224,320, 400)
              and  ct.Status in (1,2,3,4,5)
    UNION  ALL 
        SELECT  col1, col2, ...
            FROM  CompleteTxn ct
            left outer join  CompleteItem ci  ON (ct.Id = ci.TxnId)
            left outer join  ItemDispute id  ON (ct.Id = id.TxnId
                      and  ci.Id = id.ItemId
                          )
            left outer join  Merchant mc  ON (ct.MerchantId = mc.Id)
            left outer join  AdditionalTxnInfo addti  ON (ct.Id = addti.TxnId)
    where  (ct.PartitionKey>=55 AND  ct.PartitionKey<=56 )
      and  ( ct.TxnCompleteTime >= '2016-08-01 17:00:00'
        and  ct.TxnCompleteTime <= '2016-08-09 17:00:00'
           )
      and  ct.MnoId in (22,24,25,23,26,220,221,200,223,224,320, 400)        ) t ;

通过

订购联盟全部

持续时间/获取时间 :104.895秒/ 0.00028秒

选择* FROM(

SELECT col1,col2,... FROM FailedOrder ct left outer join FailedItem ci ON(ct.Id = ci.TxnId)left outer join ItemDispute id ON(ct.Id = id.TxnId and ci.Id = id。 ItemId)左外连接商家mc ON(ct.MerchantId = mc.Id)左外连接AdditionalTxnInfo addti ON(ct.Id = addti.TxnId)其中(ct.PartitionKey&gt; = 55 AND ct.PartitionKey&lt; = 56)和( ct.TxnCompleteTime&gt; =&#39; 2016-08-01 17:00:00&#39;和ct.TxnCompleteTime&lt; =&#39; 2016-08-09 17:00:00&#39;)和ct .MnoId(22,24,25,23,26,220,221,200,223,224,320,400)和ct.Status in(1,2,3,4,5)

UNION ALL

SELECT col1,col2,... FROM CompleteTxn ct left outer join CompleteItem ci ON(ct.Id = ci.TxnId)left outer join ItemDispute id ON(ct.Id = id.TxnId and ci.Id = id。 ItemId)左外连接商家mc ON(ct.MerchantId = mc.Id)左外连接AdditionalTxnInfo addti ON(ct.Id = addti.TxnId)其中(ct.PartitionKey&gt; = 55 AND ct.PartitionKey&lt; = 56)和( ct.TxnCompleteTime&gt; =&#39; 2016-08-01 17:00:00&#39;和ct.TxnCompleteTime&lt; =&#39; 2016-08-09 17:00:00&#39;)和ct .MnoId in(22,24,25,23,26,220,221,200,223,224,320,400)

)t ORDER BY id desc;

4 个答案:

答案 0 :(得分:0)

根据我的假设,您正在处理大量数据近600万条记录。

1)与Union相比,Union All的速度要快得多

2)您将所有select语句带入Derived表。

3)您再次对ID进行ORDER BY(效果问题

如果您按大数据订购,将会对性能产生巨大影响。

所有结果将按顺序方式排序,因此绝对可以增加分摊成本百分比

select Col1,Col2 from SuccessOrder
UNION ALL
select Col1,Col2  from FailedOrder
UNION ALL
select Col1,Col2  from PendingOrder

答案 1 :(得分:0)

你的order by很可能是罪魁祸首。您实际上是在选择之后订购整个数据库,并根据其索引方式,可能需要很长时间。

你可以:

  • 确保表格按照(重要)
  • 的顺序编制索引
  • 全部删除订单

我不认为union all费用接近于排序所有数据的费用。

答案 2 :(得分:0)

我会恳求无知为什么工会与选择相比如此之长,比我聪明的人需要证明这一点。我使用我自己的数据库重复了您获得的结果,但开销相似。这就是说,如果您对子选择进行排序,则会丢失表的索引

select * from (
(select * from SuccessOrder order by ID limit 100)
UNION ALL
(select * from FailedOrder  order by ID limit 100)
UNION ALL
(select * from PendingOrder order by ID limit 100)
) t order by t.ID desc limit 100;

将利用索引并返回100而不会产生太多开销。如果你想要分页的所有600万行...那稍微不同,但是直接最后100是合理的,但这取决于你的id列是如何生成的,如果它相当于一个记录数字,这个答案对任何人都没有帮助。

答案 3 :(得分:0)

其中一些提示可能有所帮助:

  • 您不需要外部gulp.task('connect', function() { connect.server({ hostname: 'localhost', bin: 'C:/php/php.exe', ini: 'C:/php/php.ini', port: 8000, base: '' }); });
  • 不要返回数百万行;在MySQL中处理它们,然后只提供你需要的那些,或者总结你需要的东西。
  • 如果您只使用前几个,请参阅documentation on UNION
  • 最小化要返回的列数。额外的大量额外列是减速的一部分。
  • 如果可行,将SELECT更改为(ct.PartitionKey>=55 AND ct.PartitionKey<=56 )
  • ct.PartitionKey IN (55,56)中,将ct.TxnCompleteTime <= '2016-08-09 17:00:00'更改为<=
  • 首先使用其中一个IN和<秒进行索引。
  • 考虑将所有数据放在一个表格中。

请提供TxnCompleteTime