![](/img/trans.png)
[英]Performance Issue in Oracle (Difference between common table expressions and global temp table)
[英]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.