2013-07-26 316 views
0

好吧,這裏是我的表格模式。
我有2個表格。說表A和表B.表A的主鍵是PriKeyA bigint(50),表B的主鍵是PriKeyB varchar(255)。 PriKeyA和PriKeyB都包含相同類型的數據。
此問題所需的表A的相關字段是Last_login_date_in_A(日期),表B是主鍵本身。
我需要做的是,獲取A中的那些PriKeyA,它們不在表B的PriKeyB列中,而Last_login_date_in_A列應該大於當前日期的30天。基本上我需要表A具有一定的條件下沿的差異,表B(這是這個問題的日期)
這是我的SQL命令SQL左連接。花費太長時間。

: SELECT A.PriKeyA from A 
LEFT JOIN B ON A.PriKeyA = B.PriKeyB 
WHERE B.PriKeyB IS NULL and DATEDIFF(CURRENTDATE,Last_login_date_in_A)>30; 

然而,當我運行這個MySQL命令,它需要大約可笑的時間很長(約3小時)。表A的大小是2,50,000,表B是42,000個記錄。我認爲這個問題可能是由於PriKeyA和PriKeyB是不同的數據類型。所以我也在查詢中使用了CAST(PriKeyB as unsigned)。但那也行不通。績效有所改善。

可能的問題是什麼?我之前使用過左連接,他們從未花過這麼長時間。

+1

我會懷疑,這個問題是與數據類型,並專門與查詢中的每一行上執行轉換。 – DOK

+0

但不應該類型鑄造解決了嗎? –

+1

您的數據庫在硬件上運行。這裏沒有神奇的獨角獸,如果你至少沒有使用InnoDB,並且如果你沒有優化MySQL的設置,那麼你就會吠叫錯誤的樹。另外,當你想知道爲什麼需要太長的時間時,總是使用'EXPLAIN',MySQL會告訴你它應該怎麼做,並且推斷你要求的數據。 –

回答

2

查詢的費用似乎是這些原因:

  • 的SQL數據類型爲A的PK和B的PK是不一樣的。
  • 表A可能不具有指數Last_login_date_in_A

這意味着,在表格中的所有行必須在同一時間檢查一列,以確定是否>在30天前的標準是真正。如果A有250,000行(而不是25,000),那麼尤其如此。

在Last_login_date_in_A上添加索引可能會幫助您在這裏,但由於需要更新附加索引,也會稍微減慢表的插入/更新/刪除語句時間。

另外,你應該利用在解釋MySQL的實際選擇的查詢計劃查詢的文檔:MySQL query plan documentation

+0

它是2,50,000。這就是它在印度寫的。 –