War*_*ard 36 sql sql-server-2008-r2 query-performance
这是一个关于SQL Server 2008 R2的问题
到目前为止,我不是DBA.我是一名java开发人员,必须不时编写SQL.(主要嵌入代码中).我想知道我在这里做错了什么,如果是的话,我可以做些什么来避免它再次发生.
Q1:
SELECT something FROM (SELECT * FROM T1 WHERE condition1) JOIN ...
Run Code Online (Sandbox Code Playgroud)
Q1有14个连接
Q2与Q1相同,但有一个例外.(SELECT*FROM T1 WHERE condition1)之前执行,并存储在临时表中.
这不是相关的子查询.
Q2:
SELECT * INTO #tempTable FROM T1 WHERE condition1
SELECT something FROM #tempTable JOIN ...
Run Code Online (Sandbox Code Playgroud)
再次,14加入.
现在让我感到困惑的是,Q1花了> 2分钟(尝试了几次,以避免缓存发挥作用),而Q2(两个查询合并)花了2秒!是什么赋予了?
Kar*_*AMR 49
为什么不建议使用子查询?
数据库优化器(无论您使用的是哪种数据库)都无法始终正确地优化此类查询(使用子查询).在这种情况下,优化器的问题是选择正确的方式来连接结果集.有几种算法可以连接两个结果集.算法的选择取决于一个和另一个结果集中包含的记录数.如果您连接两个物理表(子查询不是物理表),则数据库可以通过可用统计信息轻松确定两个结果集中的数据量.如果其中一个结果集是一个子查询,那么要了解它返回的记录数是非常困难的.在这种情况下,数据库可以选择错误的连接查询计划,这将导致查询性能的急剧下降.
使用临时表重写查询旨在简化数据库优化器.在重写查询中,参与连接的所有结果集都是物理表,数据库将很容易确定每个结果集的长度.这将允许数据库选择所有可能的查询计划中保证最快的.而且,无论条件如何,数据库都会做出正确的选择.使用临时表的重写查询可以在任何数据库上很好地工作,这在便携式解决方案的开发中尤为重要.此外,重写的查询更易于阅读,更易于理解和调试.
据了解,使用临时表重写查询可能会因额外费用而导致一些减速:创建临时表.如果数据库不会被错误地选择查询计划,它将比新查询更快地执行旧查询.但是,这种放缓总是可以忽略不计.通常,创建临时表需要几毫秒.也就是说,延迟不会对系统性能产生重大影响,通常可以忽略.
重要!不要忘记为临时表创建索引.索引字段应包括在连接条件中使用的所有字段.
这里有很多事情需要解决,索引,执行计划等.测试和比较结果是要走的路.
你可以看看通常的嫌疑人,索引.查看执行计划并进行比较.确保该WHERE子句使用正确的子句.确保您使用的是索引JOINs.
这些答案肯定会对你有所帮助.
| 归档时间: |
|
| 查看次数: |
58972 次 |
| 最近记录: |