以下字段全为varchar
Table A (bid,cid必有一个为空)
------------------------
time  
bid    
cid
Table B
------------------------
bid
bname
type
Table C
----------------
cid
cname
typeTable type
---------------------
type
name1
name2需要得到这样的结果
time    bid    bname    cid    cname
但是需要对name1和name2加限制我是这样做的
select a.time, a.bid, b.name, a.cid, c.name 
from A a, B b, C c, Type, t
where a.bid = b.id 
    and a.cid = c.id 
    and (b.type = t.type or (a.bid='' and c.type = t.type))
可是这条sql在10万条记录的A表上(我还有几个表连接(这几个连接同A与B之间关系相同,应该不是它们的问题),居然执行了150多秒
请高手指点

解决方案 »

  1.   

    hehe ,告诉你吧在A表上的bid,cid 上建索引,如果 B表的bid不是主建,也在这上建索引,C表的cid也是如此。
    B表和C表的type字段建索引,如果type表的type字段不是主建,也建索引
    修改查询语句为连接查询 (join)这样处理后,如果时间在5秒以上,请来找我好了。
      

  2.   

    不过,劝楼主最好加上 limit 10000,11000 这样的字句,要不然,输出时,可是要耗费资源的。
      

  3.   

    不知道为什么所有的字段都要 varchar ,为什么不使用 int 或者 char?
      

  4.   

    楼上帅哥,我只是把DB大概描述出来了
    当然有int之类的了,总不能全写出来吧,呵呵to whalefish2001(whale)
    =============================
    我现在改成了这样了
    select a.time, a.bid, a.bname, a.cid, a.cname
    from 
    (
        select a.time, a.bid, b.name, a.cid, c.name, b.type btype, c.type ctype
        from A a, B b, C c
        where a.bid = b.id 
            and a.cid = c.id
    )a,
    `type` t
    where 
    btype = t.type or ctype = t.type
    这样一来时间变成10秒左右了,但离帅哥的5秒以内好像还有点距离啊
    烦请细说一下,limit暂时先不考虑,等等再加上去
      

  5.   

    修改查询语句为连接查询 (join)?怎么个连接方法该
    还有,不明白为什么你会这样说"不是主建,也在这上建索引"
    不要骂我哦,DB上我的确是个菜
      

  6.   

    1.有索引就一定要用索引(注意顺序)
    2.注意关联的顺序
    select a.time, from A a, B b where a.bid = b.id 

    select a.time, from A a, B b where b.bid = a.id 
    的效率是不一样的.
    尤其是当A,B表大小相差很大时.
    一般是小表放在"="右侧
      

  7.   

    hehe ,楼主没明白我的意思,
    你的那个语句还不是我想要说的。
    你的那个,能有10秒已经不错了等我吃完饭,给你写
      

  8.   

    A 表的 bid 和 cid  
    B 表的 bid 和 type ,id (id 这个字段是怎么来的我不知道,不过,如果不是主键也要加索引)
    C 表的 cid 和 type ,id (同上)
    type 表的 type 字段以上字段,如果不是这个表的主键 ,就在这个字段上,建索引,这么说,明白了吗?修改sql语句如下:
      

  9.   

    select a.time, a.bid, b.name, a.cid, c.name 
    from A a, B b, C c, Type, t
    where a.bid = b.id 
        and a.cid = c.id 
        and (b.type = t.type or (a.bid='' and c.type = t.type))这个sql语句中的 (a.bid='' and c.type = t.type) 的关系实在是值得商榷,表建的不好?还是把 a.cid='' 写错成 a.bid=''  了?
    如果楼主执意如此,则 用楼主写的程序即可,因为我不知道业务,所以,能够用join也是不太清楚的。不过,看楼主的意思,好像是可以用 left join 连接的。 具体用法,楼主自己取研究一下,好吗?
      

  10.   

    帅哥,先恭喜你啊,半个小时就多个裤衩
    你的修改后的sql呢?看不到啊
    这个表是别人建好的表,无法改
    原来是
    A是主数据表
    B是业务1表
    C是业务2表 (同一时间中业务1,2只有一个)
    T是类别表,有4个字段
    code(主键)
    name1
    name2
    type1(表示是业务1的类别还是业务2的类别)
    原来的查询没有涉及类别表,现在要把类别限制也加上去
    即在
    select .. from A, B, C where A.bid = B.id and A.cid = C.id //and filter
    这样的查询上再把类别限制也加上去,实在头痛另外我就是弄不懂为什么不为主键时才可以加索引
      

  11.   

    succeese() 
    ================
    谢谢啊,这个我会注意的
      

  12.   

    这个sql语句中的 (a.bid='' and c.type = t.type) 的关系实在是值得商榷,表建的不好?
    这个地方我是这样想的:
    如果bid可以匹配的上,那就不用or后面的这个括号的里的东西了
    如果bid匹配不上时,即bid=''时就用c表去匹配
    好似不需要啊
    直接c.type = t.type就可以了,呵呵
      

  13.   

    hehe ,不知道最后执行的时间是?
    如果有主键,mysql会自动去取主键的,这个比索引的效率要好。
    否则,就去取索引,如果都没有,那么mysql只有执行最傻的操作了:全表搜索。取主键和索引都可以直接定位,但是主键更快一些。这么说,楼主明白了吗?
      

  14.   

    最后没有给sql语句的原因是,楼主最初的sql就是最好的了。
    相反,这个 :
    select a.time, a.bid, a.bname, a.cid, a.cname
    from 
    (
        select a.time, a.bid, b.name, a.cid, c.name, b.type btype, c.type ctype
        from A a, B b, C c
        where a.bid = b.id 
            and a.cid = c.id
    )a,
    `type` t
    where 
    btype = t.type or ctype = t.type
    反而比较差。
    因为有些地方没有用到索引的直接定位功能,所以会慢。