【发布时间】: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 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);
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