合并由1700万条记录组成的表格

时间:2011-06-21 06:36:48

标签: mysql

我有3个表,其中2个表有200 000个记录,另一个表有1 800 000个记录。我使用OCN and TIMESTAMP(month,year)的2个约束合并这3个表。前两个表的月份和年份列为Monthx(包括月份,日期和年份)。和其他表作为每个月和每年的单独列。我把查询作为,

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天给出了这个查询。你告诉我这个查询是正确还是错误并给我一个确切的查询..(我给了'%b'因为我的C表有一个在JAN,MAR)形式有月份的专栏。

2 个答案:

答案 0 :(得分: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. 日期字段的翻译需要批次时间
  4. 我建议你重写表格以使用不需要翻译的字段(使用功能),但可以直接比较。
    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上,则查询应该每秒运行大约一百万行(或更多)。

答案 1 :(得分:0)

要测试您的查询是否正常,请将A,B和C中的一小部分记录导入临时数据库并对其进行测试。

您在隐式JOIN中有冗余,因为您将B.OCN加入B.OCN,B.OCN加入C.OCN,然后加入C.OCN加入A.OCN,其中可以删除。如果A.OCN = B.OCN和B.CON = C.OCN,则暗示A.OCN = C.OCN。此外,我猜你在日期比较中有裁员。