在园子里搜了很多关于sql语句优化语句的文章、看着乏味,大多都是华丽的表演测试。没一个靠谱的!
什么避免使用in、not in、联接表时小表大后等等...测试数据表结构简单。
实际应用表结构复杂三表联接查询、数量级都是50万左右、且用到全文索引,不计算I/O时间的话,要求2秒内返回结果!
表结构如下:
1.TitleInfo 表 数据大约50万
字段 CID int 主键 聚集索引,Title 非聚集索引 全文索引,其它字段在此不需要检索省略
2.BaceInfo 表 数据大约40万
字段 CID 外键引用TitleInfo 表中的CID,其它字段在此不需要检索省略
3.DetailInfo 表 数据大约35万
字段 CID 外键引用TitleInfo 表中的CID,Product varchar(255),Introduce text
Product和Infroduce 中有全文索引
要求查询:查询TitleInfo,BaceInfo表里面的信息,关键字在TitleInfo,DetailInfo表中的全文索引列出现的记录:
即:Title,Product,Introduce 中出现关键字的记录
这是我自己写的语句性能很差:
select count(BaceInfo.CID) from TitleInfo right join BaceInfo ON TitleInfo.CID=BaceInfo.CID where BaceInfo.CID not in (select CID from DetailInfo where contains(*,'"杯子"') union select CID from TitleInfo where contains(*,'"杯子"')) order by baceinfo.cid asc
请大家赐教!!!!
这口气.....
你写的查询有几个问题:
1。不见对DetailInfo表有引用。
2。外层查询的TitleInfo right join 就是个打酱油的,对结果不产生影响。
3。introduceinfo 这个表没有介绍。
4。最终结果你要记录数还是完整的记录列表?你的要求是是记录列表查询的却是记录数据。
select b.*,c.* -- 这里处理一下字段名
from
(
select cid from titleinfo
where contains(title,'杯子')
union
select cid from DetailInfo
where contains((product,Introduce),'"杯子"')
) a
inner join titleinfo b on a.cid=b.cid
left outer join BaceInfo c
on c.cid=b.cid
或者:
select a.*,c.* -- 这里处理一下字段名
from titleinfo a
left outer join BaceInfo c
on contains(a.title,'杯子')
and a.cid=c.cid
union
select a.*,c.* -- 这里处理一下字段名
from titleinfo a inner jion
(
select cid from DetailInfo
where contains((product,Introduce),'"杯子"')
) b
on a.cid=b.cid
left outer join BaceInfo c
on a.cid=c.cid
50w笔的三表连接,数据量真不算大.楼上兄弟的解答已经搞定了.
呵呵,感觉楼主这几十W的数据量用不上人家说的那种”避免in,not in之类的。。。