惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Blog — PlanetScale
Blog — PlanetScale
G
Google Developers Blog
Microsoft Security Blog
Microsoft Security Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
腾讯CDC
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Jina AI
Jina AI
雷峰网
雷峰网
T
Tailwind CSS Blog
爱范儿
爱范儿
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
酷 壳 – CoolShell
酷 壳 – CoolShell
大猫的无限游戏
大猫的无限游戏
月光博客
月光博客
博客园 - 司徒正美
I
InfoQ
Engineering at Meta
Engineering at Meta
Vercel News
Vercel News
小众软件
小众软件
U
Unit 42
Google DeepMind News
Google DeepMind News
D
DataBreaches.Net

博客园 - riccc

微服务、分库分表、分布式事务管理、APM链路跟踪性能分析演示项目 - riccc - 博客园 事务信息系统-并发控制与恢复的理论, 算法与实践-计算模型, 并发控制部分 数据库系统 - 面向应用的方法 Data Modeling Technologies - ER, IE, Barker, IDEF1X, EXPRES-G, ORM 计划清单 声明:***本博客停止更新维护*** ANTLR SQL解析器代码 Hibernate Shards 数据的水平、垂直切割(三)- Hibernate Shards结构 Hibernate Shards 数据的水平、垂直切割(二)- Hibernate Shards基本演示 Hibernate Shards 数据的水平、垂直切割(一)- Hibernate测试环境 IKVM - 0.42.0.3 .NET平台上的Java实现 NVelocity 1.1 vs StringTemplate 3.2 Castle NVelocity - 1.1 - riccc IoC - StructureMap 2.6.1 AOP - PostSharp 2.0 AOP - AspectSharp 2.1.1.0 IoC - Castle Windsor - 扩展container 2.1 IoC - Castle Windsor 2.1 Mono.Cecil - 0.6
SQL Server用错关联方式
riccc · 2010-09-26 · via 博客园 - riccc

SQL Server中不少怪异问题都是由用错关联方式引起的,从2000到2005有所改善,但2005的查询优化引擎还是存在“犯傻”的时候

1. 问题1
现象:一个存储过程,通过一个服务程序调用,长时间不能结束,数据库服务器显示该存储过程执行到某个语句时一直等待在那,数据库服务器内存充足,CPU消耗几乎没有。把这个存储过程拿出来直接在查询分析器中执行,参数跟程序调用时完全类似,立即结束且结果正确
解决方案:排除了阻塞等原因,因为放在查询分析器中执行时一切正常,从执行计划等方面无法看出任何问题,也排除了磁盘IO等方面的原因,实在想不到其他的了。最后怀疑是SQL Server查询引擎JOIN方式选的不对,强制使用HASH JOIN后,程序调用恢复正常
疑点:一直没有发现程序调用与直接使用查询分析器执行,这2者之间存在哪些差别,会影响到SQL Server查询优化决策

2. 问题2
现象:一个不算复杂的查询,用到了row_number函数分页,一执行就会导致服务器8个CPU全部100%,很长时间(好几分钟)不能结束。使用临时表实现同样的效果,几秒钟完成
语句1:
   SELECT
      ROW_NUMBER() OVER(ORDER BY  COLUMNNAME1  ASC) as FC_ROWNUMBER
      ,COUNT(1) OVER() AS FC_COUNT
      ,* FROM (
      SELECT 产品 as COLUMNNAME1,产品描述 as COLUMNNAME2,入库日期 as COLUMNNAME7,预期数量 as COLUMNNAME8
         ,入库数量 as COLUMNNAME9,行状态 as COLUMNNAME10,供应商 as COLUMNNAME11,供应商名称 as COLUMNNAME12
      FROM V_收货明细查询
      where   入库日期 >=  '2010-7-1'
   ) TT_MAINKEY_TMP
执行计划:

语句2:
SELECT * FROM (
   SELECT
      ROW_NUMBER() OVER(ORDER BY  COLUMNNAME1  ASC) as FC_ROWNUMBER
      ,COUNT(1) OVER() AS FC_COUNT
      ,* FROM (
      SELECT 产品 as COLUMNNAME1,产品描述 as COLUMNNAME2,入库日期 as COLUMNNAME7,预期数量 as COLUMNNAME8
         ,入库数量 as COLUMNNAME9,行状态 as COLUMNNAME10,供应商 as COLUMNNAME11,供应商名称 as COLUMNNAME12
      FROM V_收货明细查询
      where   入库日期 >=  '2010-7-1'
   ) TT_MAINKEY_TMP
) TT_RET_TMP
WHERE FC_ROWNUMBER BETWEEN 1 AND 1000
ORDER BY  COLUMNNAME1  ASC
执行计划:

仅仅是把SQL作为一个子查询,在外面多包装了一下,整个查询计划就不一样了。排除了统计信息不准确、索引碎片等状况
2个查询计划中对3个表使用的都是聚集索引扫描,基本上就是关联算法不一样
因为用的并行查询,三个表数据都有几十万和一百多万,嵌套循环需要执行几十万次,所以单个查询导致所有CPU都100%。估计高CPU是由于Lazy Spool操作造成的

解决方案:
强制用HASH JOIN,或者加索引避免SQL Server出错,或者用临时表绕过去