首页 新闻 会员 周边

sql 查询优化 求教

0
悬赏园豆:120 [已关闭问题] 关闭于 2014-12-19 16:08

select * from

(select *from A inner join B on A.Id=B.Id left join C on C.Id=B.Id left join D on D.Id=C.Id)

where [no]>(select MAX([no])-1 from (select top 1000[no] from  

(select *from A inner join B on A.Id=B.Id left join C on C.Id=B.Id left join D on D.Id=C.Id) 

order by [no]) as MaxId) order by [no]

怎么将  (select *from A inner join B on A.Id=B.Id left join C on C.Id=B.Id left join D on D.Id=C.Id)  优化,不查询两次, 

比如 这样:

select * from

(select *from A inner join B on A.Id=B.Id left join C on C.Id=B.Id left join D on D.Id=C.Id) as table

where [no]>(select MAX([no])-1 from (select top 1000[no] from  

table 上面的 表

order by [no]) as MaxId) order by [no]

还有个问题,(select *from A inner join B on A.Id=B.Id left join C on C.Id=B.Id left join D on D.Id=C.Id)  这个 sql 千变万化,不可能是死的,也就是不可能写成视图

情·深的主页 情·深 | 初学一级 | 园豆:16
提问于:2014-12-10 11:59
< >
分享
所有回答(7)
0

首先你的no是哪个表的?如果是A或者是B的,那left join的C和D都是多余的。

看你的sql语句,貌似是想去排名1000以后的数据。为啥不直接用row_number()排个序,然后直接rownum >1000呢?

幻天芒 | 园豆:37175 (高人七级) | 2014-12-10 12:27

先说明、(select *from A inner join B on A.Id=B.Id left join C on C.Id=B.Id left join D on D.Id=C.Id) 这是 例子, 里面是什么查询 是 随时变化的,你不管里面是什么,反正是一张很多表的结果表。

而且 其它你也不用在意, 只要 想办法 把 (select *from A inner join B on A.Id=B.Id left join C on C.Id=B.Id left join D on D.Id=C.Id) 这个 让数据库不进行二次查询就好

支持(0) 反对(0) 情·深 | 园豆:16 (初学一级) | 2014-12-10 12:43

@科维: 你搞个临时 表,把这个结果存一下就只有一次了。

支持(0) 反对(0) 幻天芒 | 园豆:37175 (高人七级) | 2014-12-10 13:14

@幻天芒: 可是我有一个 疑问、我这张表估计就是现查 现用、而且每次结果不一样,要是10W人 一起查询, 那不得 建10QW临时表, 机子直接死机了,而且速度 肯定很慢

支持(0) 反对(0) 情·深 | 园豆:16 (初学一级) | 2014-12-10 14:43

@科维: 不要担心这个,,,你要是10w个并发,一般系统也撑不住!

支持(0) 反对(0) 幻天芒 | 园豆:37175 (高人七级) | 2014-12-10 17:09
0

select MAX([no])-1 from (select top 1000[no] from  

(select *from A inner join B on A.Id=B.Id left join C on C.Id=B.Id left join D on D.Id=C.Id) 

order by [no]) as MaxId

这句话,我没有看错的话,应该只有一个值吧?

爱编程的大叔 | 园豆:30839 (高人七级) | 2014-12-10 12:41

select MAX([no])-1 from (select top 1000[no] from  

(select *from A inner join B on A.Id=B.Id left join C on C.Id=B.Id left join D on D.Id=C.Id) 

order by [no]) as MaxId 这不重要、  重要的是   (select *from A inner join B on A.Id=B.Id left join C on C.Id=B.Id left join D on D.Id=C.Id)  这个出现了多次,我想让它 只查询一次、 

支持(0) 反对(0) 情·深 | 园豆:16 (初学一级) | 2014-12-10 14:42

@科维: 既然你认为不重要那就不重要好了。

1、没有一个方法是可以放之天下而皆准的,应用环境很重要。

2、你这个查询,别指望啥10万人一起查询了,1万人都死了。

3、楼上说的临时表,放在存储过程里面执行,应该是还行的。

4、看出来你不是问这个问题,而是在问一类问题,可能你编程中经常出现这样的查询,

但是有时候良好的数据库设计胜过到处问怎样写古里古怪的SQL语句。

5、问题太抽象,看书效果好过问人。

支持(0) 反对(0) 爱编程的大叔 | 园豆:30839 (高人七级) | 2014-12-10 14:51

@爱编程的大叔:  那就求教一个SQL  优化吧。  select top 11 a.[no],a.[clausefirst],a.[title] from (select * from T_keylink where zkey='人参' and content_no in (select content_no from T_keylink where zkey='脑中风' ) and content_no in(select content_no from T_keylink where zkey='三七' ) and content_no in(select content_no from T_keylink where zkey='癫痫' ) and content_no in(select content_no from T_keylink where zkey='作用' ) ) as a left join (select * from T_keylink where  zkey='脑中风') as C on a.content_no=C.content_no  left join (select * from T_keylink where  zkey='三七') as D on a.content_no=D.content_no  left join (select * from T_keylink where  zkey='癫痫') as E on a.content_no=E.content_no  left join (select * from T_keylink where  zkey='作用') as G on a.content_no=G.content_no   where a.[no]>(select MAX([no])-1 from (select top 12 a.[no] from (select * from T_keylink where zkey='人参' and content_no in (select content_no from T_keylink where zkey='脑中风' ) and content_no in(select content_no from T_keylink where zkey='三七' ) and content_no in(select content_no from T_keylink where zkey='癫痫' ) and content_no in(select content_no from T_keylink where zkey='作用' ) ) as a left join (select * from T_keylink where  zkey='脑中风') as C on a.content_no=C.content_no  left join (select * from T_keylink where  zkey='三七') as D on a.content_no=D.content_no  left join (select * from T_keylink where  zkey='癫痫') as E on a.content_no=E.content_no  left join (select * from T_keylink where  zkey='作用') as G on a.content_no=G.content_no   order by [no]) as MaxId) order by [no]  这是肯定能出数据的, 不过很 慢,不理想 有什么 快的方法没

支持(0) 反对(0) 情·深 | 园豆:16 (初学一级) | 2014-12-10 15:56

@科维: 看你这个SQL太费劲,你能够用文字描述这段SQL要达到的目的吗?

支持(0) 反对(0) 爱编程的大叔 | 园豆:30839 (高人七级) | 2014-12-10 16:16

@爱编程的大叔:  就是输入一串 关键字,进行分词、然后 重组 sql 查询出 想要的数据 并进行分页

支持(0) 反对(0) 情·深 | 园豆:16 (初学一级) | 2014-12-10 16:43

@科维: 这个真得建议你看书了。

1、你这个分词不知道是哪个分词,如果是那个分词的话,建议google lucence

2、分页不是关键,而且与这个SQL应该是无关的,啥时候加都可以,不应该这时候说。

3、我看你的SQL就是在奇怪你那些关键词的条件,不知道为什么要这样加。

所以可以的话,你还是描述清楚一下这些条件的要求。

比如,我有一个数据表Table,对字段Content_No进行条件筛选,条件之间是并集还是交集?

结果要求是。如果可能,你可以模拟一组数据出来,然后再模拟你要的结果数据集。

这样可能大家容易理解一点。

支持(0) 反对(0) 爱编程的大叔 | 园豆:30839 (高人七级) | 2014-12-10 16:49
0

针对这个语句,和你的需求, 用row_number()是最好的选择~

AshEs丶 | 园豆:251 (菜鸟二级) | 2014-12-10 15:52

 row_number()  算了, 太慢了, 慢得 要命 根本就 我用过几次,小数据还行,大数据。 就没法了,我还没查询都耗费大量时间了

支持(0) 反对(0) 情·深 | 园豆:16 (初学一级) | 2014-12-10 15:54

@科维: 大数据下row_number() 会比你的 max + top +order by +子查询 慢的话 ,我无话可说了

对于你来说,看书效果真的好过问人。

支持(0) 反对(0) AshEs丶 | 园豆:251 (菜鸟二级) | 2014-12-10 16:04

@科维: row_number() 慢?! 汗颜,不知道你是怎么测的? row_number() 明显比你上面写的一大堆性能高, sql 2012 里还有个 offset 分页,性能更好

支持(0) 反对(0) xmj112288 | 园豆:126 (初学一级) | 2014-12-12 17:39
0

代码解决把,sql太麻烦就把结果拿到代码里面处理

茂茂 | 园豆:2892 (老鸟四级) | 2014-12-11 15:54
0

这sql写的基础太差了

row_number()的性能肯定比自己做max top 快的,慢是你的其他条件的问题,还有这sql真心渣。

1、多个条件可以合并啊为什么要用多个in 不能把多个条件的结果查出来在in吗

2、查下CTE,类似 with temp as (select 。。。); 

3、你在where里面已经是很强的判断了,left jion 是想干嘛,而且还是同一张表,你left jion完全没有作用

4、最后告诉你在没有row_number()的时候,分页是  top (N+1)*n   再倒序   再top n  再倒序 取到第N页的  

select * from (select top 10 * from (select top 10*10 * from a order by createtime asc) as temp order by temp.createtime desc )  temp1 order by temp1.createtime asc

5、对分词汉字这些数据量大有专门的解决方案

菜园的 | 园豆:204 (菜鸟二级) | 2014-12-15 11:39

left join ,是避免 漏网之鱼。 我试过很多SQL ,唯独这个SQL 能查询出数据 这还是关键字少的情况,要是关键字多了,估计我SQL 得爆满

支持(0) 反对(0) 情·深 | 园豆:16 (初学一级) | 2014-12-15 11:45

去 row_number()速度 真的 很慢 、100W 条数据的时候,那直接 排序都得花10来秒,然后再赛选数据,又得花10来秒, 谁受得了

支持(0) 反对(0) 情·深 | 园豆:16 (初学一级) | 2014-12-15 11:46

本来我一直用 row_number  可惜,现在 不用了, 太慢了。 小数据的时候 没感觉出来

支持(0) 反对(0) 情·深 | 园豆:16 (初学一级) | 2014-12-15 11:47

@科维: row_number的字段加索引

支持(0) 反对(0) 凡一二三 | 园豆:85 (初学一级) | 2014-12-15 15:07
0

建议你附加需求和语句,这样别人能给你更多的方法,你单独写语句这种优化方案有限。

pursuer.chen | 园豆:162 (初学一级) | 2014-12-15 21:49
0

只有慢慢学习了   数据库 真难  

情·深 | 园豆:16 (初学一级) | 2014-12-19 16:06
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册