两句SQL语句就这一点不同,为什么第二条就不行呢?请教SQL语句原理,还请众兄弟帮忙(100分)

我认为嵌套查询使用merge join基本上不会有什么效果
因为嵌套查询和连接的做法不一样
即使子查询得到的结果集是有序的,也仍然需要循环查找匹配的记录
 
>>沉香屑
就是有效果的呀!(上面我写的最后一个例子)
1.本来第二个Top超过30000就出错!加了merge join后就不出错了!
2.加了merge join之后,查询速度也变慢了!
 
>>沉香屑
对了,你说的SET ROWCOUNT,是不是全局的!设了之后,是不是所有的SQL语句都用
这个设置(这样就麻烦了)!
SET ROWCOUNT基本上可以代替Top,但如果用SET ROWCOUNT配合,如何取10-20条记录?
(我想不出来!注:ID并非从小到大排序!)
麻烦你了,谢谢!
 
抱歉,我现在没有sqlserver
因此不能测试:(
 
>>沉香屑
哦,不过还是谢了!
---------------
望其它FW再帮忙看看,谢谢了!
 
SELECT TOP 10 ID_Field into #temp_table
FROM Table
WHERE CangKu = '库1' order by ShengChanPH, ID_Field)) AND (CangKu = '库1')

SELECT TOP 10 * FROM Table
WHERE ID_Field NOT IN (select ID_Field from #temp_table)
order by ShengChanPH,ID_Field
drop table #temp_table
 
>>zwma
SELECT TOP 10 ID_Field into #temp_table
FROM Table
WHERE CangKu = '库1' order by ShengChanPH, ID_Field)) AND (CangKu = '库1')
------------------------------------------------------------------
是个办法,但如果Top的数据一大,这样写入临时表的速度是不是太慢了!
 
首先,我们要确定这个问题,是SQL出错,还是执行效率低,时间长造成超时不能完成
如果是超时,也就是说30秒同步不能执行完成,可以采用异步方式,这样,你想等多长
就等多长,还有就是把同步等待的30秒加大,比如到1小时,应该也能出来,呵呵。
当然,更好的办法是优化SQL语句,数据库,建议你用存储过程,具体怎样优化你也是
高手,就慢慢优化吧,呵呵
应该不是SQL有错误,这种情况就不讨论了
 
当数据量大的时候最好不要用not in,非常耗系统资源,很有可能会使系统崩溃
可以用以下方法代替
比如说要实现:
select * from table1
where id not in (select id from table2)
改为:
select * into #tmptable from table1
delete #tmptable
where id in (select id from table2)
select * from #tmptable
drop table #tmptable
 
>>同步等待的30秒加大,比如到1小时,应该也能出来
SS2000兄开玩笑了!你说的没错,优化SQL语句,不过我只是不明白多加一个ORDER BY条件
差别会这么大!(一个几十个毫秒,一个超时),所以找更优化的语句的同时,想问一下诸位
SQL语句的原理!谢谢了!

>>独酷求败
1.酷兄,我的SQL不是两张表中进行排除,是要取一张表中的中间的一个记录集!
(例如20-30的记录)
2.如果是你那样写,在大数据集的库里,我建议你不要替换你写的第一种方法!
select * into #tmptable from table1 这样的语句只会慢吧!
(我在我的第一个贴子里的第一个例子在6万的数据库中查40000到40020的记录集只用
了几十个毫秒!)
3.Not in的效率确实不好,的确不是最好的解决办法!谢谢!
最好的方法是smallbs兄说的!
(想一想:不要在(取 N次 记录的) N次 上做文章,可以在 上次记录的ID_table的最大值 上做文章。)

>>smallbs兄
我已在你的基础上想到了好办法!不过我想再晚点贴上来!也许大家还有更好的办法!

>>all
非常感谢,大家能否再帮我想想有没有更好的办法!
另外,我在上面贴子关于SQL语句的几个问题能否帮我回答一下!
1.本来第二个Top超过30000就出错!加了merge join后就不出错了!
2.加了merge join之后,查询速度也变慢了!(详情请参看上面的贴子)
 
order by是个比较慢的操作
因为join操作可以利用索引
而order by要得到全部记录集再进行排序,也就是基本上不能利用索引
 
NOT in 很耗内存和cpu資源,建议不要使用

 
不好意思,这个问题拖的时间有点久了,不过我还想再放一个星期!
看看是否还有哪位FW会给出更好的办法!
--------------
一个星期后我给出我最后的解决方案! 谢谢大家!
并不见得是最好的方案!:)
 
没有情交,可最好不要这样使用 IN 或 not IN 这个语法。
SELECT TOP 10 * FROM Table
WHERE (ID_Field NOT IN
(SELECT TOP 10 ID_Field
FROM Table
WHERE CangKu = '库1' order by ID_Field)) AND (CangKu = '库1')

为什么呢?
因为优化SQL语句的最基本定律就是尽量少的读取数据表。
可这样使用它们,那就反其道而行了。
因为主语句中 SELECT TOP 10 * FROM Table 每查出一条记录都会让
IN 后面的语句查一遍数据库的,
这样多消耗系统资源。
不信可找一大点的数据库试试。

当然,大型数据库可能对这方面的处理作了很多优化,反到表现的不象小型数据库那么明显,
但其结果还是很有影响的。

象这个语句怎么写的?
应该这样,先把

不过,这就10条到也无所谓了,
只是很让人不理解的你为何这样作。

SQL语句的优化还是很有用的,
有空可参考一下我的那个“一堆SQL”。

http://www.playicq.com/dispdoc.php?t=&id=1479
 
>>沉香屑(order by 基本上不能利用索引)
不太可能吧!

>>程云,cloudjava
IN和Not IN 的确不是一个高效的方法!谢谢了!

>>程云兄
我这样做的目的是能够从一个数据表中拉一部分数据到本地给客户显示(这当中可以断开
联接状态!)当客户在往下拉更多的数据时,再从数据表拉接下来的一部分数据!

>>smallbs(可以在 上次记录的ID_table的最大值 上做文章)
谢谢!(不过多个字段的order by 还是费了些脑筋)
----------------------------------------------------
下面是我的解决方法:
(办法是想出来的,呵呵)
Select Top N Field1,Field2,Field3,Field4 From Table
Where ((Field1>LastFieldValue1)
or (Field1=LastFieldValue1 and Field2>LastFieldValue2)
or (Field2=LastFieldValue2 and Field3>LastFieldValue3)
or (Field3=LastFieldValue3 and Field4>LastFieldValue4))
order by Field1,Field2,Field3,Field4

注:LastFieldValue1-4是每次查询后要保存的最后一条记录的数据!
(帖子再放两天,方法仅供FW们参考)
 
是这样的
索引只有在做连接时才有效
 
分太少了,不太好意思:)
 
顶部