2011-06-21 62 views
1

我有3個表,其中2個表包含200 000條記錄,另一個表包含1 800 000條記錄。我使用2個限制條件合併這3個表格,即OCN and TIMESTAMP(month,year)。前兩個表的月份和月份的列爲Monthx(包括月份,日期和年份)。和其他表作爲每個月和每年的單獨列。我把查詢作爲,包含1700萬條記錄的合併表

mysql--> insert into trail 
    select * from A,B,C 
    where A.OCN=B.OCN 
    and B.OCN=C.OCN 
    and C.OCN=A.OCN 
    and date_format(A.Monthx,'%b')=date_format(B.Monthx,'%b') 
    and date_format(A.Monthx,'%b')=C.IMonth 
    and date_format(B.Monthx,'%b')=C.month 
    and year(A.Monthx)=year(B.Monthx) 
    and year(B.Monthx)=C.Iyear 
    and year(A.Monthx)=C.Iyear 

我給這個查詢4天它仍然running.could妳告訴我這個查詢是否是正確的還是錯誤的,並提供我一個準確的查詢。(我給了前達'%b',因爲我的C表有一個有JAN,MAR格式的月份。

+0

請不要使用隱含的'where'加入,將它埋在1989年,它屬於哪裏。 (a.ocn = b.ocn和date_format(A.Monthx,'%b')= date_format(B.Monthx,'%b')....'使用顯式連接代替' – Johan

回答

0

要測試您的查詢是否正常,請將A,B和C中的一小部分記錄導入臨時數據庫並對其進行測試。

由於您正在使用B.OCN加入A.OCN,使用C.OCN加入B.OCN,然後將C.OCN加入到A.OCN,因此可以刪除隱含JOIN中的冗餘。如果A.OCN = B.OCN和B.CON = C.OCN,則隱含A.OCN = C.OCN。此外,我想你在日期比較中有冗餘。

1

請不要在隱含的地方使用連接,將它埋在1989年,它屬於哪裏。使用明確連接,而不是

select * from a inner join b on (a.ocn = b.ocn and 
date_format(A.Monthx,'%b')=date_format(B.Monthx,'%b') .... 

查詢的這種選擇部分(不得不重寫,因爲我拒絕處理'89語法)

select * from A 
inner join B on (
    A.OCN=B.OCN 
    and date_format(A.Monthx,'%b')=date_format(B.Monthx,'%b') 
    and year(A.Monthx)=year(B.Monthx) 
) 
inner join C on (
    C.OCN=A.OCN 
    and date_format(A.Monthx,'%b')=C.IMonth 
    and date_format(B.Monthx,'%b')=C.month 
    and year(B.Monthx)=C.Iyear 
    and year(A.Monthx)=C.Iyear 
) 

擁有的問題很多

  1. 在字段上使用函數將會消除在該字段上使用索引的任何機會。
  2. 你正在做很多重複測試。如果(A = B)(B = C)然後它在邏輯上得出(A = C)
  3. 日期字段的翻譯需要很多時間

我建議你重寫你的表使用的是不需要翻譯的字段(使用函數),但可以直接進行比較。
yearmonth : char(6)例如201006可以索引和比較快得多。

如果表中A,B,C有一個字段名爲ym比您的查詢短可能是:

INSERT INTO TRAIL 
SELECT a.*, b.*, c.* FROM a 
INNER JOIN b ON (
    a.ocn = b.ocn 
    AND a.ym = b.ym 
) 
INNER JOIN c ON (
    a.ocn = c.ocn 
    AND a.ym = c.ym 
); 

如果你把指標上ocn(可能主要指數)和ym查詢應運行約每秒一百萬行(或更多)。