速度可能提高1000的 EXISTS 最高级的用法, 我也是无意中用到的, 跟兄弟们分享一下

cncharles 2008-10-16 10:28:08
我要有一个非常复杂的视图,数据非常大, 其中有三个重要字段。批号:PN, 结算日期: BalanceDate, 出货日期: ShipDate. 现在要在基于这个视图上统计, 以出货日期准指定时间段里与结算日期重复的批号.
刚才开始以这个视图
SELECT * FROM vwFinPNCostShipDate B WHERE BalanceDate<'2007-04-01' AND EXISTS(
SELECT 1 FROM vwFinPNCostShipDate WHERE PN=B.PN AND ShipDate BETWEEN '2007-04-01' AND '2008-03-31')


N分钟都没有结果,一不小心写成了这样

SELECT * FROM vwFinPNCostShipDate B WHERE BalanceDate<'2007-04-01' AND EXISTS(
SELECT 1 WHERE PN=B.PN AND ShipDate BETWEEN '2007-04-01' AND '2008-03-31')


注意 EXISTS 中没有 FROM 马上就出结果了, 兄弟们遇到过没有, 也就是说EXISTS 自身引用可以不用FROM.
...全文
168 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
cncharles 2008-10-17
  • 打赏
  • 举报
回复
谢谢楼上关注, 请用我上面给出的代码测试
hyde100 2008-10-17
  • 打赏
  • 举报
回复
看看
rockyvan 2008-10-17
  • 打赏
  • 举报
回复
--我用我的实际数据库的数据作了个测试结果如下:
1、没有FROM语句
WHERE EXISTS (SELECT 1 WHERE [IODate] BETWEEN '2008-08-01' AND '2008-08-31')
(10616 個資料列受到影響)
执行时间0秒

2、有FROM语句
WHERE EXISTS (SELECT 1 FROM [Test].[dbo].[IOData] WHERE [IODate] BETWEEN '2008-08-01' AND '2008-08-31')
(31013 個資料列受到影響)
执行时间3秒

--很明显结果不一样,如果你的结果是一样的,很可能是巧合
--执行时间确实差了3秒,但是影响的数据条数相差很大
rockyvan 2008-10-17
  • 打赏
  • 举报
回复
--我用我的实际数据库的数据作了个测试结果如下:
1、没有FROM语句
WHERE EXISTS (SELECT 1 WHERE [IODate] BETWEEN '2008-08-01' AND '2008-08-31')
(10616 個資料列受到影響)
执行时间0

2、有FROM语句
WHERE EXISTS (SELECT 1 FROM [Test].[dbo].[IOData] WHERE [IODate] BETWEEN '2008-08-01' AND '2008-08-31')
(31013 個資料列受到影響)
执行时间3

--很明显结果不一样,如果你的结果是一样的,很可能是巧合
cncharles 2008-10-17
  • 打赏
  • 举报
回复
继续测试, 下面的测度结果符合预期, 我的结论貌似正确, 现在等牛人解释原因。如果这个结果成立好像与SELECT 语法有冲突。

DECLARE @T TABLE (PN VARCHAR(20), BalanceDate DATETIME, ShipDate DATETIME)

INSERT INTO @T
SELECT 'TD701', '2007-03-01', '2007-07-01' --此条语句符合要求
UNION ALL SELECT 'TD702', '2007-03-02', '2007-07-01' --此条语句符合要求
UNION ALL SELECT 'TD703', '2007-05-01', '2007-10-01'--此条语句不符合要求

SELECT * FROM @T B WHERE BalanceDate<'2007-04-01' AND EXISTS
(SELECT 1 FROM @T WHERE PN=B.PN AND ShipDate BETWEEN '2007-04-01' AND '2008-03-31')

SELECT * FROM @T B WHERE BalanceDate<'2007-04-01' AND EXISTS
(SELECT 1 WHERE ShipDate BETWEEN '2007-04-01' AND '2008-03-31')
rockyvan 2008-10-17
  • 打赏
  • 举报
回复
看看先!
cncharles 2008-10-17
  • 打赏
  • 举报
回复
我把视图的数据放插入到一个临时表中测试过, 结果是一样的

SELECT * INTO #ShipDate FROM vwFinPNCostShipDate

SELECT * FROM #ShipDate B WHERE BalanceDate<'2007-04-01' AND EXISTS(
SELECT 1 FROM #ShipDate WHERE PN=B.PN AND ShipDate BETWEEN '2007-04-01' AND '2008-03-31')
上面的语句与下面的语句结果一样
SELECT * FROM #ShipDate B WHERE BalanceDate<'2007-04-01' AND EXISTS(
SELECT 1 WHERE ShipDate BETWEEN '2007-04-01' AND '2008-03-31')
cncharles 2008-10-17
  • 打赏
  • 举报
回复
结果是正确的, 不信你们自己测试一下。
ilovewalk 2008-10-17
  • 打赏
  • 举报
回复
MARK.
-狙击手- 2008-10-17
  • 打赏
  • 举报
回复
SELECT * FROM vwFinPNCostShipDate B WHERE BalanceDate<'2007-04-01' AND EXISTS(
SELECT 1 WHERE PN=B.PN AND ShipDate BETWEEN '2007-04-01' AND '2008-03-31')

等价于:

SELECT * FROM vwFinPNCostShipDate B WHERE BalanceDate<'2007-04-01' AND ShipDate BETWEEN '2007-04-01' AND '2008-03-31'

这个和你的
SELECT * FROM vwFinPNCostShipDate B WHERE BalanceDate<'2007-04-01' AND EXISTS(
SELECT 1 FROM vwFinPNCostShipDate WHERE PN=B.PN AND ShipDate BETWEEN '2007-04-01' AND '2008-03-31')
已经不是一个意思了

你可以 自己写几个简单测试例子一试就知道
fcuandy 2008-10-17
  • 打赏
  • 举报
回复
你的写法,子查询里读的是当前行。

数据结果都错了,再谈效率有什么意义,呵呵
rucypli 2008-10-16
  • 打赏
  • 举报
回复
看样执行计划有差别,结果一样吗
水族杰纶 2008-10-16
  • 打赏
  • 举报
回复
select 1 where 1=1
/*

-----------
1
*/
华芸智森 2008-10-16
  • 打赏
  • 举报
回复
SELECT * FROM vwFinPNCostShipDate B WHERE BalanceDate<'2007-04-01' AND EXISTS(
SELECT 1 WHERE PN=B.PN AND ShipDate BETWEEN '2007-04-01' AND '2008-03-31')

SELECT * FROM vwFinPNCostShipDate B WHERE BalanceDate<'2007-04-01' AND ShipDate BETWEEN '2007-04-01' AND '2008-03-31'
的结果有区别吗?
wzy_love_sly 2008-10-16
  • 打赏
  • 举报
回复

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧