使用临时表的子查询查看 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 子句需要非常长时间的主要内容,如果未能解决你的问题,请参考以下文章

与查询具有相同 WHERE 子句的子查询

在 WHERE 子句中重用选择表达式的子查询

Hive Query 不允许 >= 在 where 子句的子查询中

使用不同 WHERE 子句获取聚合的子查询

如何使用数千个 WHERE 子句优化 SQL 查询

SQLAlchemy - WHERE 子句中的子查询