两个表,业务表A,数据量在2000万以上;字典表B,数据量在13万左右。
A中主键a是个编号,表示了该记录的所属类别(一级分类,二级分类,三级分类……),及流水号(样式为:1201020304123456,其中12为主分类,01、02、03、04分别为一二三四级分类,123456为业务流水号)。B中记录了类别号(b)和该类别的其他一些信息。
问题:
查询出A中主类别属于12,且类别编号不存在于B中的数据,保存到C表中(表结构同A)。
A表中各类数据量的比例:不属于主类别12的有几十万;属于12分类,但分类号不存在于B中的数据量<100万。已经做的工作:
1. 查询A表中符合要求的数据,速度还可以接受。
方法1:select * A where left(a,2)='12' and (not exists (select '1' from B where B.b=left(A.a,10)));
方法2:select * A where left(a,2)='12' and left(a,10) not in (select b from B);理论上not in要比not exists慢很多。
2. 将1中的*替换为count(*),查询符合要求的记录个数。 超慢。 哪位达人知道原因?
3. 将1的返回结果集进行C表的插入,超慢。运行十几个小时无结果,放弃。
 insert into C select * A where left(a,2)='12' and (not exists (select '1' from B where B.b=left(A.a,10)));各位有最优的SQL实现吗?

解决方案 »

  1.   

    不止是查询性能,主要的问题是实现符合要求数据的C表插入。
    insert into C select * A where left(a,2)='12' and (not exists (select '1' from B where B.b=left(A.a,10))); (十几个小时未成功)
    和 select * A where left(a,2)='12' and (not exists (select '1' from B where B.b=left(A.a,10)));(大约几分钟, <15min)
    为何相差如此之大。
      

  2.   

    select * A where
    晕,写错了,少了from。
      

  3.   

    try:
    select a.* from A inner join b
    on left(a,2)='12' and B.b=left(A.a,10)
      

  4.   

    我运行了这个sql,一样的问题,只是select很快,insert into select就很慢了,select count(*) 也慢。
      

  5.   


    insert into select就很慢了,select count(*) 也慢贴语句出来看看
      

  6.   

    select count(*) from A inner join B on left(A.a,2)='12' and B.b=left(A.a,10);insert into C
    select A.* from A inner join B on left(A.a,2)='12' and B.b=left(A.a,10);
    C表是和A同结构的表。只是把语句做了简单的修改,有何高见?
      

  7.   

    单是运行 select A.* from A inner join B on left(A.a,2)='12' and B.b=left(A.a,10); 速度还是挺快的
      

  8.   

    建立索引没有?
    你可以用
    select a.* from A inner join b
    on left(a,2)='12' and B.b=left(A.a,10) 
    生成临时表,再插入C,COUNT(*) 是A表还是B表?
    COUNT(字段试试)
      

  9.   

    有索引,A.a和B.b是索引列。。left(a,2)这种函数是否会破坏索引,即,使索引不起作用而进行全表扫描?
    select count(A.a) from A inner join B on left(A.a,2)='12' and B.b=left(A.a,10)。 一个字:很慢!我建立空表C进行插入,和建立临时表区别不会很大吧。可以将结果生成C表。值得研究下。谢谢先!
      

  10.   

    EXPLAIN一下SQL语句,看看瓶颈在什么地方
      

  11.   

    create table c as select a.* from A inner join b
    on left(a,2)='12' and B.b=left(A.a,10)
      

  12.   

    create table c as select a.* from A inner join b
    on left(a,2)='12' and B.b=left(A.a,10)
    ______________________________________________
    嗯,大批量插入时不用索引
    瓶颈在io上
    插入完毕再建索引
      

  13.   

    EXPLAIN 很好用,B表重构,忘记建索引了。虽然速度一般,但至少十来分钟出来了。解决方法:确认索引都建了。使用exists,
    select count(*) from A where left(a,2)='12' and (not exists (select '1' from B where B.b=left(A.a,10))); 问题解决,结贴。
    最近adsl超慢,现在才来结贴。见谅。
    最后谢谢两位。