You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Join返回10000行而非1行,三SQL查询成本差异排查求助

分析与解决方案

看起来你碰到了两个棘手的问题:Query3的执行成本是另外两个的5倍,而且Join返回了10000行(本该只有1行)。咱们先从行数爆炸的问题入手,因为这大概率是Query3变慢的根源。

一、先搞定Join返回过多行的问题

这种情况基本是关联逻辑错了或者数据匹配出了问题,先排查这几点:

  1. 检查你的关联条件是不是写反/写错了
    你的prices表的Security是int类型,是关联securities.ID的外键——也就是说,正确的关联应该是p.Security = s.ID。如果你的Query3里写成了p.Security = s.Security(把外键和证券名称列关联),那麻烦就大了:

    • 一个是int,一个是nvarchar,会触发隐式数据类型转换,直接导致prices表的主键索引用不上
    • 如果securities表里有不止一行的Security='USD'(哪怕ID不同),Join的时候就会把prices里对应这些ID的所有行都拉出来,直接造成行数爆炸
  2. 先确认securities表的目标数据唯一性
    跑这两条查询看看:

    SELECT COUNT(*) FROM securities WHERE ID = 75;
    SELECT COUNT(*) FROM securities WHERE Security = 'USD';
    

    如果第一条返回1,第二条返回大于1,说明有多个ID对应同一个证券名称,这时候如果你用Security='USD'来关联,肯定会匹配到多条securities记录,进而和prices的行产生笛卡尔积,行数直接飙升。

二、再解决Query3执行成本过高的问题

搞定行数问题后,咱们来优化执行效率,核心就是让查询尽量利用现有的索引:

  1. 先看看Query3的写法是不是浪费了索引
    prices表的主键是(Security, Date),这是个天然的覆盖索引(主键索引包含所有列),所以针对特定Security、特定日期范围的查询应该跑得飞快。比如高效的写法应该是直接过滤:

    SELECT p.Date, p.Price
    FROM prices p
    WHERE p.Security = 75  -- 直接用已知的ID,不用Join securities
      AND p.Date BETWEEN '2017-10-01' AND '2017-10-03';
    

    如果Query3里非要先Join securities再过滤,而且关联条件还错了,数据库就会先做全表扫描或者大表Join,再过滤数据,成本能不高吗?

  2. 能不Join就别Join
    既然你已经知道目标证券的ID是75,完全可以直接在prices表里用Security=75过滤——除非你需要同时返回证券名称这类其他字段,否则多余的Join纯粹是增加执行成本。

  3. 看看执行计划找瓶颈
    针对Query3,打开SQL Server的执行计划(SSMS里按Ctrl+M启用实际执行计划就行),重点看这几点:

    • 有没有出现表扫描/聚集索引扫描(如果应该用索引查找的话,说明索引没用到)
    • Join的类型:Nested Loops是高效的,要是用了Merge Join或者Hash Join而且涉及大表,成本肯定高
    • 执行计划里的“实际行数”和“估计行数”是不是差很多?如果是,说明统计信息过时了,跑下面的语句更新一下:
      UPDATE STATISTICS prices;
      UPDATE STATISTICS securities;
      

三、给你个优化后的Query3示例

如果确实需要关联securities表(比如要返回证券名称),这么写就没问题:

SELECT s.Security, p.Date, p.Price
FROM securities s
INNER JOIN prices p ON s.ID = p.Security
WHERE s.ID = 75
  AND p.Date >= '2017-10-01'
  AND p.Date <= '2017-10-03';

这个写法的逻辑是:

  1. 先通过securities.ID=75找到唯一的一行(用主键索引,飞快)
  2. 再通过prices.Security=75和日期范围找对应的价格行(用prices的主键索引)
  3. 完全避免了隐式转换,把索引的作用发挥到最大,执行成本会降下来很多

内容的提问来源于stack exchange,提问作者arnoldh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:22:29