繁体   English   中英

为什么临时表和子选择之间存在巨大的性能差异

[英]Why is there a HUGE performance difference between temp table and subselect

这是一个关于 SQL Server 2008 R2 的问题

到目前为止,我不是 DBA。 我是一名 Java 开发人员,时不时要编写 SQL。 (主要嵌入在代码中)。 我想知道我是否在这里做错了什么,如果是,我可以做些什么来避免它再次发生。

问题 1:

SELECT something FROM (SELECT * FROM T1 WHERE condition1) JOIN ...

Q1 有 14 个连接

Q2 与 Q1 相同,只有一个例外。 (SELECT * FROM T1 WHERE condition1) 之前执行,并存储在临时表中。

这不是相关的子查询。

问题 2:

SELECT * INTO #tempTable FROM T1 WHERE condition1
SELECT something FROM #tempTable  JOIN ...

再次,14 加入。

现在让我感到困惑的是 Q1 花费了 > 2 分钟,(尝试了几次,以避免缓存起作用)而 Q2(两个查询相结合)花费了 2 秒!!! 是什么赋予了?

为什么不建议使用子查询?

数据库优化器(无论您使用什么数据库)并不总是能正确优化此类查询(使用子查询)。 在这种情况下,优化器的问题是选择正确的方式来连接结果集。 有几种算法可以连接两个结果集。 算法的选择取决于一个结果集中和另一个结果集中包含的记录数。 如果连接两个物理表(子查询不是物理表),数据库可以通过可用的统计数据轻松确定两个结果集中的数据量。 如果结果集之一是子查询,那么了解它返回多少条记录是非常困难的。 在这种情况下,数据库可以选择错误的join查询计划,从而导致查询性能的急剧下降。

使用临时表重写查询旨在简化数据库优化器。 在重写的查询中,所有参与连接的结果集都将是物理表,数据库将很容易确定每个结果集的长度。 这将允许数据库选择所有可能的查询计划中保证最快的。 而且,无论什么条件,数据库都会做出正确的选择。 使用临时表重写的查询在任何数据库上都可以很好地工作,这在可移植解决方案的开发中尤其重要。 此外,重写的查询更易于阅读、更易于理解和调试。

据了解,使用临时表重写查询可能会由于额外费用而导致一些速度变慢:临时表的创建。 如果数据库不会错误地选择查询计划,它将比新查询更快地执行旧查询。 然而,这种放缓总是可以忽略不计的。 通常,临时表的创建需要几毫秒。 即延迟不能对系统性能产生显着影响,通常可以忽略。

重要的! 不要忘记为临时表创建索引。 索引字段应包括连接条件中使用的所有字段。

这里有很多事情要处理,索引、执行计划等。测试和比较结果是要走的路。

你可以看看通常的嫌疑人,索引。 查看执行计划并比较它们。 确保WHERE子句使用正确的子句。 确保您在JOINs上使用索引。

这些答案肯定会对你有很大帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM