使用临时表的子查询查看 where 子句需要非常长时间
Posted
技术标签:
【中文标题】使用临时表的子查询查看 where 子句需要非常长时间【英文标题】:Where clause on view using sub query with temp table taking exceptionally long time 【发布时间】:2016-03-16 22:46:58 【问题描述】:当我使用 select * from view where column in (xxxx) 并使用子查询(这是一个简单的 id 列表)时,执行时间比简单地输入数字列表要长近 1000 倍,示例如下。
A) 执行耗时 0ms
SELECT Name FROM TMS.dbo.vPerson p WHERE p.personid IN (1,2,3,4)
B) 执行需要 3200 毫秒
SELECT personid INTO #persons FROM tcPerson p WHERE p.personid IN (1,2,3,4)
SELECT Name FROM TMS.dbo.vPerson p
WHERE p.personid IN (SELECT personid FROM #persons)
我确保每次都清除缓存,但似乎没有正当理由说明这需要这么长时间。
临时表实际上只是一个包含 4 个 ID 的列表。它的创建可以忽略,where查询中值的选择可以忽略
所有帮助将不胜感激。
【问题讨论】:
有点困惑,A 做 1 个查询,B 做 5 个……(你的最后一条语句总共有 3 个查询) 是的,有 4 个选择,但是,单独选择 personid 最多只需要 1ms,这将剩下 3000 秒的时间。 好的,但是在你写它的那一行实际上并没有执行一些 linq。所以 A 可能实际上还没有处理 linq。你需要访问它。放入秒表行,并找出您的哪些查询需要时间,因为 A 与 B 完全不同...... B 的第一行肯定......但它仍然在不同的终端容器上......一个可能是本地内存另一个没有索引的远程远程重载sql server.. 通常需要表定义(包括索引)和查询计划来帮助进行性能调整。 如果在 IN 上使用 EXISTS 会怎样 【参考方案1】:这是您的查询:
SELECT Name
FROM TMS.dbo.vPerson p
WHERE p.personid IN (SELECT personid
FROM TMS.dbo.tcPerson p
WHERE p.personid IN (SELECT personid FROM #persons)
)
有时,IN
比其他版本的查询更难优化。您可以通过查看执行计划来判断。我确实注意到这个查询相当于:
SELECT Name
FROM TMS.dbo.vPerson p
WHERE p.personid IN (SELECT personid FROM TMS.dbo.tcPerson p) AND
p.person_id IN (SELECT personid FROM #persons)
嵌套的子查询是不必要的。如果您在 tcPerson(personid)
和 #persons(personid)
上有索引,则此查询应该没问题。
【讨论】:
实际的临时表是从一个更大的查询中派生出来的,它只返回值。如果我采用这 4 个值并单独运行,我会得到与上述值相同的值,但仍然是一个有效点 在重新阅读时,我注意到您是正确的,我不需要子查询选择 ID 并已相应更新,但是问题仍然存在,即从临时表中选择以提供 4 个列表视图的 where 子句的 ids 花费了很多时间以上是关于使用临时表的子查询查看 where 子句需要非常长时间的主要内容,如果未能解决你的问题,请参考以下文章