2016-08-09 102 views
2

我有3個表(SuccessOrder,FailedOrder和PendingOrder)具有相同的列。每張表都有超過200萬條記錄。我需要結合這3個表中的所有數據,並通過CreatedDate對它們進行排序,以顯示在我的門戶中。我使用UNION ALL來組合所有表格的結果。MySQL聯盟性能問題

如果我執行每個子查詢,在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還有其他的選擇嗎?

是否有可能從3個查詢創建視圖沒有UNION ALL?

以下是從工作臺測試的個人和聯合查詢。我看不出太大的差別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); 

聯盟所有全無爲了通過

持續時間/提取時間: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 ; 

聯盟所有與ORDER BY

持續時間/提取時間:104.895秒/ 0.00028秒

SELECT * FROM(

SELECT COL1,COL2,... FROM FailedOrder CT左外部聯接FailedItem ci ON(ct.Id = ci.TxnId)left外部聯接ItemDispute id ON(ct.Id = id.TxnId和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)和(ct.TxnCompleteTime> ='2016-08-01 17:00:00'和ct.TxnCompleteTime < ='2016-08-09 17:00:00')和ct.MnoId in (22,24,25,23,26,220,221,200,223,224,320,400)和ct.Status在(1,2,3,4,5)

UNION ALL

SELECT COL1,COL2,... FROM CompleteTxn CT左外加入CompleteItem ci ON(ct.Id = ci.TxnId)left outer join ItemDispute id ON(ct.Id = id.TxnId和ci.Id = id。ItemId)left outer join Merchant mc ON(ct.MerchantId = mc.Id)left outer join AdditionalTxnInfo addti ON(ct.Id = addti.TxnId)其中(ct.PartitionKey> = 55 AND ct.PartitionKey < = 56)和( 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 ORDER BY id desc;

+1

如果您刪除't.ID'的訂單,那麼我猜它會快得多,否則應該需要時間。 – 1000111

+0

爲什麼你要一次檢索600萬條記錄?這是三個表掃描。索引在這裏用處不大。 – e4c5

+0

我們不是一次檢索600萬條記錄。我們對每個子查詢都有條件。我們需要檢查從這3個表中的搜索,並通過選定的字段(大多數ID)排序,並顯示前100條記錄給用戶分頁 – rkvegiraju

回答

0

根據我的假設,你正在處理巨大的數據近600萬條記錄。

1)比較時,聯盟,聯盟所有的遠遠快

2)你正在服用的所有select語句到派生表。

3)同樣,你在做ORDER BY的ID(性能問題

它會給巨大的性能的影響,如果你在巨大的數據順序通過。

所有結果將得到有序中依次所以肯定分揀費百分比將增加

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

認真請你在你的問題草案這一個@rkvegiraju – mohan111

+0

我執行我的查詢工作臺並在說明中添加每個查詢的持續時間。在** UNION ALL **和** UNION ALL - ORDER BY **之間沒有看到太大的區別** – rkvegiraju

0

order by是最有可能在這裏的罪魁禍首。您在選擇之後基本上訂購了您的整個數據庫,並且取決於其索引的方式,這可能需要很長時間。

,你可以:

  • 確認表由你(重要的)命令是什麼
  • 通過產品總數

刪除訂單,我不認爲對索引的union all成本接近排序所有數據的成本。

+0

由於有序列屬於可能包含重複項的聯合,因此這並不意味着主鍵上的索引不可用?必須有一個以工會爲基礎的新索引,據我所知,這是不可能完成的。那是對的嗎? –

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列是如何產生的,如果它相當於一個記錄號碼,這個答案沒有任何幫助。

+0

LIMIT上的子查詢爲我工作。我在0.53秒內得到了結果。 我有2個案件。 1.需要分頁記錄總數 2.有時,我需要將數據導出到Excel文件。 Linit在這些情況下不起作用。 – rkvegiraju

0

一些技巧可以幫助:

  • 你不需要外SELECT
  • 不要返回數百萬行的;在MySQL中處理它們,然後只交付你需要的,或者總結你所需要的。
  • 如果您打算只使用前幾項,請參閱documentation on UNION
  • 儘量減少要返回的列數。額外的大量額外列是減速的一部分。
  • 改變,如果實際
  • (ct.PartitionKey>=55 AND ct.PartitionKey<=56)ct.PartitionKey IN (55,56)ct.TxnCompleteTime <= '2016-08-09 17:00:00',改變<=<
  • 首先有一個INs,TxnCompleteTime秒。
  • 考慮將所有數據放在一張表中。

請提供SHOW CREATE TABLE