簡體   English   中英

MYSQL將帶有子查詢的緩慢更新轉換為(更快?)聯接

[英]MYSQL converting slow update with subquery to (faster?) join

我有一個查詢,該查詢使用mysql中的子查詢變得非常慢,最多需要幾分鍾,而我所做的所有其他查詢都相當快。

正如我發現的那樣,子查詢很可能不是一個好主意,所以我想將此子查詢轉換為聯接,就像我對所有其他使用子查詢的查詢所做的一樣,這對性能產生了很大影響。

我的大多數其他查詢都非常簡單,但這讓我很生氣。

這是一個例子。

我有客戶和賬單。 客戶有多個賬單。 法案有州。 並且賬單具有參數“ whatever”。

我需要更新“所有帳單都處於狀態1或2且帳單無論參數不是2的所有客戶端”

由於我無法找到解決方法,因此我使用了反轉功能,即“所有沒有帳單的客戶都不在狀態1和狀態2,並且帳單的任何參數不是2”

這是我現在正在使用的帶有子查詢的兩個變體,一個使用count,一個使用“ not in”,但是它們似乎同樣慢。

update client cl , bill bi 
set cl.parameter = "parameter1" 
where cl.parameter="parameter2" 
    and bi.whatever != "2" 
    and bi.client_id = cl.id  
    and (select count(cl.id) 
            from bill bi 
                where bi.client_id = cl.id 
                    and bi.state!="state0" 
                    and bi.state != "state1" 
        ) = 0;

在mysql狀態“發送數據”中變慢

update client cl , bill bi 
set cl.parameter = "parameter1"  
    where  cl.parameter="parameter2" 
        and bi.whatever != "2" 
        and bi.client_id = cl.id  
        and cl.id not in  (select distinct cl.id 
                                from bill bi  
                                    where bi.client_id = cl.id 
                                        and  ( bi.state!="state1" 
                                        and bi.state != "state2" 
                            ) ;

在mysql狀態“復制到臨時表”中變慢

我嘗試了幾個小時,但沒有該慢速子查詢,我無法將其轉換為有用的東西。 任何人都可以給我一個想法,如何使用聯接或比現在更快的速度執行此操作?

更新

多虧了DRapp,這產生了完全相同的結果,並且速度更快。 對於我到目前為止可以測試的內容,查詢時間減少到幾秒鍾,而幾分鍾之前。

select
  c.id,
  sum( if( b.State IN ( "State1", "State2" ), 1, 0 )) as OkStatesCnt,
  sum( if( b.State NOT IN ( "State1", "State2" ) or b.whatever=2, 1, 0 )  ) as AnyOtherState
from
  client c
     join bill b
        ON c.id = b.client_id
where
  c.parameter = "parameter2"
   group by
      c.id
  having
      OkStatesCnt > 0
  AND AnyOtherState = 0

UPDATE client cl,
  ( full select query from above ) as PreQualified
 set cl.parameter = "parameter1"
 where cl.id = PreQualified.id

為了預先確保將包括哪些客戶端,您可以單獨運行此查詢...

select
      c.id,
      sum( if( b.State IN ( "State1", "State2" ), 1, 0 )) as OkStatesCnt,
      sum( if( b.State IN ( "State1", "State2" ), 0, 1 )) as AnyOtherState
   from
      client c
         join bill b
            ON c.id = b.client_id
           AND b.whatever != "2"
   where
      c.parameter = "parameter2"
       group by
          c.id
   having
          OkStatesCnt > 0
      AND AnyOtherState = 0

如果實際上是您要查找的內容,則可以將其實施到更新中,例如

UPDATE client cl,
      ( full select query from above ) as PreQualified
   set cl.parameter = "parameter1"
   where cl.id = PreQualified.id

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM