【问题标题】:MySQL Union Performance IssueMySQL 联合性能问题
【发布时间】:2016-12-15 00:50:30
【问题描述】:

我有 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 个查询创建视图?

以下是从工作台测试的个人和联合查询。我认为 UNION ALLUNION 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);

Union All withour order by

持续时间/获取时间: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) 左外连接 Merchant mc ON (ct.MerchantId = mc.Id) 左外连接 AdditionalTxnInfo addti ON (ct.Id = addti.TxnId) where (ct.PartitionKey>=55 AND ct.PartitionKey= '2016-08-01 17:00:00' and ct.TxnCompleteTime

联合所有

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) 左外连接 Merchant mc ON (ct.MerchantId = mc.Id) 左外连接 AdditionalTxnInfo addti ON (ct.Id = addti.TxnId) where (ct.PartitionKey>=55 AND ct.PartitionKey= '2016-08-01 17:00:00' and ct.TxnCompleteTime

) t ORDER BY id desc;

【问题讨论】:

  • 如果你删除 order by t.ID 那么我想它会快得多,否则它应该需要时间。
  • 您到底为什么要一次检索 600 万条记录?这是三个表扫描。索引在这里用处不大。
  • 我们不会一次检索 600 万条记录。我们对每个子查询都有条件。我们需要检查这 3 个表中的搜索并按选定字段(主要是 ID)对它们进行排序,并通过分页向用户显示前 100 条记录

标签: mysql performance union


【解决方案1】:

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

1)与 Union 相比,Union All 快得多

2)您正在将所有选择语句放入派生表中。

3)你再次对 ID 进行 ORDER BY(性能问题

如果您对 Huge Data 执行 Order by,将会对性能产生巨大影响。

所有结果都将按顺序排序,因此肯定会增加排序成本百分比

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

【讨论】:

  • 说真的,你能在你的问题中起草这个@rkvegiraju
  • 我在工作台中执行了我的查询,并在描述中添加了每个查询的持续时间。 UNION ALLUNION ALL - ORDER BY 之间没有太大区别
【解决方案2】:

您的order by 很可能是这里的罪魁祸首。您实际上是在 select 之后对整个数据库进行排序,并且取决于它的索引方式,这可能需要很长时间。

你可以:

  • 确保根据您订购的内容对表格进行索引(重要)
  • 一起删除订单

我不认为union all 的成本接近对所有数据进行排序的成本。

【讨论】:

  • 由于有序列属于可能包含重复的联合,这是否意味着主键上的索引不可用?必须在联合上建立一个新索引,据我所知,这是无法做到的。对吗?
【解决方案3】:

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

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 列是如何生成的,如果它相当于一个记录号,这个答案没有帮助一个。

【讨论】:

  • 子查询限制对我有用。我在 0.53 秒内得到了结果。我还有2个案例。 1. 需要统计总记录分页 2. 有时,我需要将数据导出到 Excel 文件。在这些情况下,Linit 将不起作用。
【解决方案4】:

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

  • 你不需要外部SELECT
  • 不要返回数百万行;在 MySQL 中处理它们,然后只提供您需要的那些,或者总结您需要的。
  • 如果您只打算使用前几个,请参阅documentation on UNION
  • 尽量减少要返回的列数。额外的大量额外列是减速的一部分。
  • 如果可行,将 (ct.PartitionKey&gt;=55 AND ct.PartitionKey&lt;=56 ) 更改为 ct.PartitionKey IN (55,56)
  • ct.TxnCompleteTime &lt;= '2016-08-09 17:00:00' 中,将&lt;= 更改为&lt;
  • 首先有一个 IN 的索引,其次是 TxnCompleteTime
  • 考虑将所有数据放在一个表中。

请提供SHOW CREATE TABLE

【讨论】:

    猜你喜欢
    • 2020-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多