其中,B 的数据结构 是A表的一个子集,用户的原始配置放置于A中,其他用户调用这个配置的话,共有部分的属性还是在A表中,个性配置部分是在B表中,最后由 A.B两个表一起来组合出 一个完整的配置。
现在要求从配置记录表C中去读userID为某值的 所有配置信息
配置表 A :
ID x y m n ownerID
个性配置表 B:
ID AID m n userID
配置记录表 C:
ID,AID,userID
现在要求是,在配置记录表C中取出某userID的所有记录;如果在B表中也有AID的个性的配置,则用A表的 x,y 和B表的m,n 来一起组合成一个完整的配置表;如果在B表中不存在此AID,则直接从A表中取得 x,y,m,n。
相当于是 select AID from C where userID =xxx 取出来的AID 有些是单独属于A的,就是没得个性配置的,有些是A,B都有的,就是有个性配置的,现在要全部取出来在组合成一个新的集合
我是这样考虑的,先从A表中取出所有userID的记录,但是排除在B中存在的
select * from A where ownerID = 1 and not exists (select 1 from B where B.AID = A.ID and n.userID = 1)
然后在取出个性配置中此userID的记录和A 表组合成一个完整的记录
select A.x,A.y,B.m,B.n from B,A where B.AID=A.ID and B.userID =1
然后把这2个集合 union all
最后在 和 配置记录表中的取出来的 AID 进行 inner join
但是数据量都不大每个表也就万条记录左右,最后查询一次居然要4,5秒钟的时间。请问这种该有什么好的方法去优化呢?
13 个解决方案
#1
select a.id,A.x,A.y,isnull(B.m,A.m) as m,isnull(B.n,a.n) as n
from c inner join a on c.aid = a.id
left join b on a.id = b.aid
where c.UserID = 1
#2
4,5秒钟 对于每个表近万条记录,应该算是可以的吧!
#3
速度挺快的啊,要不你就用存储过程吧
#4
select * from A where ownerID = 1 and not exists (select 1 from B where B.AID = A.ID and n.userID = 1)
这个可以修改成left join 的
select
a.*
from
left join b
on
a.id=b.aid
where
c.userid=1
and
b.aid is null
#5
exists该为left连接试试。
#6
左联的效率高于exists么?
#7
不一定,但你这个改了可能提高,也可能不变
#8
我的想法是先在配置表A,B里面各取各的,(因为如果在B表中有AID相应的记录,就必须用B表来组合一个)再union all组合成一个集合M,在和记录表来 inner join,取出M和C AID 相同的值
NBDBA 用的isnull 来代替了我第一步的工作,但是我看了看,好像执行的时间更多了?
这个isnull效率如何呢
NBDBA 用的isnull 来代替了我第一步的工作,但是我看了看,好像执行的时间更多了?
这个isnull效率如何呢
#9
好像语句应该
关键,你的C、B两表的UserID有无索引,所有表的aid是否有索引。
select a.id,A.x,A.y,isnull(B.m,A.m) as m,isnull(B.n,a.n) as n
from c inner join a on c.aid = a.id
left join b on a.id = b.aid and b.UserID = 1
where c.UserID = 1
关键,你的C、B两表的UserID有无索引,所有表的aid是否有索引。
#10
都没建索引,我想对于w条记录,sql不用索引也不会慢嘛,结果查询一次4,5秒,不知道是不是我的思路不对
#11
恩,我加了这userID的,只是执行速度也没变快,还是要4秒左右
数据不多,为啥速度这样慢呢,方法思路不对?
哦,对了,我还在 select A.ID,A,X 这里加了几个函数,是取相应值的,不会是这个的问题吧,我ctrl +L 看了看,那些函数消耗基本为0,应该不是这个问题
#12
在外键上加索引,尽量不用函数
#13
你的索引观点不对,表查询经常需要连接的,1w和1w连接的可能结果是1亿。
连接字段(很多业务上就是唯一的)家聚集索引几乎是必须的,这与数据量几乎无关。
常用查询条件增加索引也是提高速度的方法。
所以,如果w的数据不多的话,那4、5秒不会算长的。
函数先去掉测试,比较有无函数的执行时间就知道函数的影响多少了,而不应该这方面以查询计划为准。
连接字段(很多业务上就是唯一的)家聚集索引几乎是必须的,这与数据量几乎无关。
常用查询条件增加索引也是提高速度的方法。
所以,如果w的数据不多的话,那4、5秒不会算长的。
函数先去掉测试,比较有无函数的执行时间就知道函数的影响多少了,而不应该这方面以查询计划为准。
#1
select a.id,A.x,A.y,isnull(B.m,A.m) as m,isnull(B.n,a.n) as n
from c inner join a on c.aid = a.id
left join b on a.id = b.aid
where c.UserID = 1
#2
4,5秒钟 对于每个表近万条记录,应该算是可以的吧!
#3
速度挺快的啊,要不你就用存储过程吧
#4
select * from A where ownerID = 1 and not exists (select 1 from B where B.AID = A.ID and n.userID = 1)
这个可以修改成left join 的
select
a.*
from
left join b
on
a.id=b.aid
where
c.userid=1
and
b.aid is null
#5
exists该为left连接试试。
#6
左联的效率高于exists么?
#7
不一定,但你这个改了可能提高,也可能不变
#8
我的想法是先在配置表A,B里面各取各的,(因为如果在B表中有AID相应的记录,就必须用B表来组合一个)再union all组合成一个集合M,在和记录表来 inner join,取出M和C AID 相同的值
NBDBA 用的isnull 来代替了我第一步的工作,但是我看了看,好像执行的时间更多了?
这个isnull效率如何呢
NBDBA 用的isnull 来代替了我第一步的工作,但是我看了看,好像执行的时间更多了?
这个isnull效率如何呢
#9
好像语句应该
关键,你的C、B两表的UserID有无索引,所有表的aid是否有索引。
select a.id,A.x,A.y,isnull(B.m,A.m) as m,isnull(B.n,a.n) as n
from c inner join a on c.aid = a.id
left join b on a.id = b.aid and b.UserID = 1
where c.UserID = 1
关键,你的C、B两表的UserID有无索引,所有表的aid是否有索引。
#10
都没建索引,我想对于w条记录,sql不用索引也不会慢嘛,结果查询一次4,5秒,不知道是不是我的思路不对
#11
恩,我加了这userID的,只是执行速度也没变快,还是要4秒左右
数据不多,为啥速度这样慢呢,方法思路不对?
哦,对了,我还在 select A.ID,A,X 这里加了几个函数,是取相应值的,不会是这个的问题吧,我ctrl +L 看了看,那些函数消耗基本为0,应该不是这个问题
#12
在外键上加索引,尽量不用函数
#13
你的索引观点不对,表查询经常需要连接的,1w和1w连接的可能结果是1亿。
连接字段(很多业务上就是唯一的)家聚集索引几乎是必须的,这与数据量几乎无关。
常用查询条件增加索引也是提高速度的方法。
所以,如果w的数据不多的话,那4、5秒不会算长的。
函数先去掉测试,比较有无函数的执行时间就知道函数的影响多少了,而不应该这方面以查询计划为准。
连接字段(很多业务上就是唯一的)家聚集索引几乎是必须的,这与数据量几乎无关。
常用查询条件增加索引也是提高速度的方法。
所以,如果w的数据不多的话,那4、5秒不会算长的。
函数先去掉测试,比较有无函数的执行时间就知道函数的影响多少了,而不应该这方面以查询计划为准。