- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
除了表中可能存在的行数之外,这些示例查询中的一个是否比另一个成本更高?
SELECT * FROM dbo.Accounts WHERE AccountID IN (4,6,7,9,10)
SELECT * FROM dbo.Accounts WHERE AccountID NOT IN (4,6,7,9,10)
最佳答案
一般来说NOT IN
尽管可以构建相反的场景,但成本会更高。
首先,假设AccountId
是 Accounts
的主键 table 。IN (4,6,7,9,10)
将需要 5 次索引查找,这意味着逻辑 IO 是 5 * 索引的深度(每次查找都需要从根向下导航到中间页并精确到一个叶页)。NOT IN (4,6,7,9,10)
将需要一个完整的扫描和一个过滤器(pushable non sargable predicate 意味着它被插入扫描而不是作为一个单独的操作符)这意味着逻辑 IO 将等于索引的叶节点中的页面数 + 非叶节点的数量水平。
看到这个
CREATE TABLE #Accounts
(
AccountID INT IDENTITY(1,1) PRIMARY KEY,
Filler CHAR(1000)
)
INSERT INTO #Accounts(Filler)
SELECT 'A'
FROM master..spt_values
SET STATISTICS IO ON
SELECT * FROM #Accounts WHERE AccountID IN (4,6,7,9,10)
/* Scan count 5, logical reads 10*/
SELECT * FROM #Accounts WHERE AccountID NOT IN (4,6,7,9,10)
/*Scan count 1, logical reads 359*/
SELECT index_depth, page_count
FROM
sys.dm_db_index_physical_stats (2,object_id('tempdb..#Accounts')
, DEFAULT,DEFAULT, 'DETAILED')
退货
index_depth page_count
----------- --------------------
2 358
2 1
查看病理上不同的情况,其中
全部 的行满足
IN
条款,因此他们都不是
NOT IN
SET STATISTICS IO OFF
CREATE TABLE #Accounts
(
AccountID INT ,
Filler CHAR(1000)
)
CREATE CLUSTERED INDEX ix ON #Accounts(AccountID)
;WITH Top500 AS
(
SELECT TOP 500 * FROM master..spt_values
), Vals(C) AS
(
SELECT 4 UNION ALL
SELECT 6 UNION ALL
SELECT 7 UNION ALL
SELECT 9 UNION ALL
SELECT 10
)
INSERT INTO #Accounts(AccountID)
SELECT C
FROM Top500, Vals
SET STATISTICS IO ON
SELECT * FROM #Accounts WHERE AccountID IN (4,6,7,9,10)
/*Scan count 5, logical reads 378*/
SELECT * FROM #Accounts WHERE AccountID NOT IN (4,6,7,9,10)
/*Scan count 2, logical reads 295*/
SELECT index_depth,page_count
FROM
sys.dm_db_index_physical_stats (2,OBJECT_ID('tempdb..#Accounts'), DEFAULT,DEFAULT, 'DETAILED')
退货
index_depth page_count
----------- --------------------
3 358
3 2
3 1
(由于 uniquifier 已添加到聚集索引键中,因此索引更深)
IN
仍然实现为 5 次等式查找,但这次每次查找时读取的叶页数远大于 1。叶页排列在一个链表中,SQL Server 继续沿此导航,直到遇到不匹配的行寻找。
NOT IN
现在实现为 2 个范围搜索
[1] Seek Keys[1]: END: #Accounts.AccountID < Scalar Operator((4)),
[2] Seek Keys[1]: START: #Accounts.AccountID > Scalar Operator((4))
带有残差谓词
WHERE ( #Accounts.AccountID < 6
OR #Accounts.AccountID > 6 )
AND ( #Accounts.AccountID < 7
OR #Accounts.AccountID > 7 )
AND ( #Accounts.AccountID < 9
OR #Accounts.AccountID > 9 )
AND ( #Accounts.AccountID < 10
OR #Accounts.AccountID > 10 )
因此可以看出,即使在这种极端情况下,SQL Server 能做的最好的事情就是跳过查看
NOT IN
之一的叶页。值。甚至当我倾斜分布使得
AccountID=7
时有点令人惊讶。记录比
AccountID=4
流行 6 倍那些它仍然给出了相同的计划,并且没有重写它作为范围寻找 7 的任何一侧,类似地在减少
AccountID=4
的数量时记录为 1 计划恢复为聚集索引扫描,因此似乎仅限于仅针对索引中的第一个值考虑此转换。
SELECT AccountID, COUNT(DISTINCT P.page_id) AS NumPages
FROM #Accounts
CROSS APPLY sys.fn_PhysLocCracker(%%physloc%%) P
GROUP BY AccountID
ORDER BY AccountID
给出这些结果
AccountID NumPages
----------- -----------
4 72
6 72
7 73
9 72
10 73
加起来
NumPages
总共给出了 362 个,反射(reflect)了某些叶页包含 2 个不同的
AccountId
的事实。值。这些页面将被搜索者访问两次。
SELECT COUNT(DISTINCT P.page_id) AS NumPages
FROM #Accounts
CROSS APPLY sys.fn_PhysLocCracker(%%physloc%%) P
WHERE AccountID <> 4
给
NumPages
-----------
287
所以,
IN
版本:
=4
访问 1 个根页面、1 个中间页面和 72 个叶页面
(74)
=6
访问 1 个根页面、1 个中间页面和 72 个叶页面
(74)
=7
访问 1 个根页面、1 个中间页面和 73 个叶页面
(75)
=9
访问 1 个根页面、1 个中间页面和 72 个叶页面
(74)
=10
访问 1 个根页面、1 个中间页面和 73 个叶页面
(75)
NOT IN
版本:
<4
访问 1 个根页面、1 个中间页面和 1 个叶页面
(3)
>4
访问 1 个根页面、1 个中间页面和 287 个叶页面
(289)
read-ahead
有关。机制。可以(在开发实例上)使用跟踪标志来禁用此机制并验证逻辑读取现在是否按上述描述的预期报告。
This is discussed further in the comments to this blog post.
关于sql - SQL 'not in' 比 SQL 'expensive' 多 'in' 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5890338/
这篇文章的更通用的标题是 MySql Sum different columns in same table based on value of another row, group by yet a
我收到“昂贵的方法调用”和“空值比较昂贵”的警告,我想知道如何解决这些问题。 void Update() { CheckCollision(); }
这主要是出于好奇。 我最近处理的一些 VHDL 代码中的一个片段类似于以下内容: led_q <= (pwm_d and ch_ena) when pwm_ena = '1' else ch_ena;
我经常看到人们在 GoogleIO 或 WWDC 上谈论如何在移动设备上绘制屏幕(位/像素)如此昂贵。谁能解释这是为什么? 最佳答案 因为像素绘图不使用任何图形加速硬件。例如,Java 中的像素绘图是
考虑以下类: public class Person { public String FirstName; public String LastName; public Dat
我最近偶然发现了一个有趣的问题,我想知道我的解决方案是否是最优的。 You are given an array of zeros and ones. The goal is to return th
下面哪段代码的开销更大? x = my_array.inject {|sum,i| int+=i } 或 x = eval(my_array.join('+')) 最佳答案 试试看: #!/usr/l
我将 AVPlayerViewController(就资源而言是昂贵的)嵌入到 UIViewController 中(使用包含)。我需要在导航堆栈中随后推送的 View Controller 中使用另
我想在一个紧密的循环中每秒调用它数千次。通话费贵吗?我正在使用 Windows Visual C++。 最佳答案 这是一个老问题,但我还是会回答,以防有其他人在寻找答案。 所以我们有一个日志库,它使用
刚刚看了一个电动云的demo,很有意思,但是很贵。 亲:优秀的功能 - 从我的作品中提取秘诀,并通过可重复使用的步骤使它们更加标准化 - 并行构建以加快速度并更有效地使用我的构建农场 - 从任何步骤重
我已经阅读了很多关于线程和所有涉及的同步机制的 Material 。我也理解不正确操作的危险。 我刚看了this PDC 2009 关于并行和并发的视频,这里再次提到“锁是一项昂贵的操作”。我现在在各
标题几乎概括了这一点,当读取 iPhone 应用程序的 NSUserDefaults 中存储的数据时,是否需要考虑任何性能? 是否有什么我遗漏的,或者从 NSUserDefaults 中读取的内容是微
我创建了一些非常简单的 Azure 函数。他们从 Couchbase(在 VM 上的 Azure 中运行)读取和写入数据。 我担心在 Azure Function 中与 Couchbase 建立的连接
我正在添加一些服务器端表单验证(使用 php),以防我网站的用户之一关闭了 javascript。在一种表单上,有 10 个可以更改的单独输入字段。有人可以告诉我哪种协议(protocol)会使用更少
假设我有这样的设置: Bla Yada 和这个样式定义: .toolbar { background-color: red; } 我实际上想要在 2 个“工具栏”之间有一个 2 像
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 7 年前。 Improve this qu
人们说这很贵是什么意思?我为中间存储创建了许多临时对象的实例(NSString 和 NSDate 是典型的)。我怎么知道我的程序对 NSDateFormatter 的使用是否过度? 到目前为止,我倾向
我很喜欢这个程序。有人可以告诉我我做错了什么吗?该程序提示用户输入产品目录中的产品数量。然后程序应提示用户输入产品目录中每个产品的名称和价格。输入所有产品后,程序应输出目录中最昂贵产品的产品信息(名称
我已阅读 here在 StackOverflow 上,每次您在 JavaSound 中播放剪辑时,它都会在幕后创建一个线程来播放它。如果这是真的(如果不是,请告诉我,因为我没有找到任何相关的文档/来源
在模拟器上进行性能分析时,我注意到每次在 NSUserDefaults 中保存一个 NSNumber 都需要很长时间,每个实例大约需要 600 毫秒。这是正常的吗?我有大约 5 个这样的对象需要保存,
我是一名优秀的程序员,十分优秀!