Sql server 为什么我的SQL Server连接需要更长的时间,一个表中有129条记录,而不是128条?

Sql server 为什么我的SQL Server连接需要更长的时间,一个表中有129条记录,而不是128条?,sql-server,inner-join,Sql Server,Inner Join,我正在工作中进行SQL Server的基本连接。我认为这需要花费相当长的时间才能实现(将一个大约有2000条记录的表加入到另一个大约有500条记录的表中) 以下是查询的内容: select an.AccountNumber ,d.AccountCharacteristic ,st.TotalBalance from AccountLevelData as d join Statements as st on st.AccountNumber = d.Accoun

我正在工作中进行SQL Server的基本连接。我认为这需要花费相当长的时间才能实现(将一个大约有2000条记录的表加入到另一个大约有500条记录的表中)

以下是查询的内容:

select
     an.AccountNumber
    ,d.AccountCharacteristic
    ,st.TotalBalance
from AccountLevelData as d
join Statements as st
    on st.AccountNumber = d.AccountNumber 
join #AccountNumberList as an
    on an.AccountNumber = d.AccountNumber 
where st.TimePeriod = eomonth(getdate(), -1)
#AccountNumberList
只是一个临时表,我用它将结果集过滤到我关心的帐户子集。我开始调试这个查询,并注意到如果我将
#AccountNumberList
过滤到只包含128个帐户,它会运行得非常快,但完成时间非常长,如果它包含129个帐户,则根本无法完成


我想这与SQLServer或SQLServerManagementStudio中的一个怪癖有关,但我找不到任何关于为什么或如何发生这种情况的资源。我确实注意到128=0b10000000,所以可能与位有关-一旦表中的行数超过7位表示查询优化器会做一些奇怪的事情

由于Statements表是最大的表,因此可以将查询翻转如下:

SELECT
    an.AccountNumber
,   d.AccountCharacteristic
,   st.TotalBalance
FROM 
    #AccountNumberList an
JOIN Statements st ON st.AccountNumber = an.AccountNumber AND st.TimePeriod = eomonth(getdate(), -1)
JOIN AccountLevelData d ON d.AccountNumber  = an.AccountNumber 
如果运行速度仍然低于应有速度,则需要检查表索引及其性能

例如,您可以从上述查询中排除语句,查看它对AccountLevelData表的执行情况,如果性能符合预期,则注释掉AccountLevelData联接,然后测试语句联接。继续你的测试,直到你中大奖。(不要忘记检查每个测试的执行计划)

检查所有索引(基本上,禁用所有索引,并保留要使用的索引,测试查询,如果查询执行得更快并且问题得到解决,则可以检查导致问题的索引)


您可能还需要更新索引的统计信息。所以,也要这样做

这是因为您不能为表设置索引。您可以向表中添加索引,然后查看查询执行计划以更好地优化查询。

执行计划是什么样子的?统计数据完全有可能会抛出一些东西(这是统计数据的本质,在某个地方有一个转折点),但是如果128号不是巧合,我会非常惊讶
c.AccountNumber
c别名没有在提供的查询中声明,请重新检查您的查询,第一个连接应该在主表上(accountleveldata),第二个连接应该取决于第一个连接。对不起,c应该是d-为了清楚起见,我更改了表名,忘记了编辑一些位置。关于连接顺序,结果集不重要,对吗?这只是为了帮助查询优化器?你不能只看临时表中的帐号数还有“d”和“st”中有多少帐号这些表包含多少条记录。
AccountNumber
字段上有索引吗?如第一条注释所述,检查这两个字段之间的查询计划。它们很可能不同。这可能与临时表中不正确的统计数据有关。这是一篇很好的文章,尽管它不会直接与您的问题相关,因为我猜您只填充了一次临时表:FWIW,查询优化器通常(总是?)忽略您实际指定表的顺序(除非您指示它不这样做)请不要散布这样的谬论,即在这样一个简单的查询中按不同的顺序放置表会产生任何影响。这并没有什么区别t@Nick.McDermaid我并没有散布任何谬论,我只是简单地使用连接来代替WHERE,所以查询优化器在检查它时,它将比连接整个表的数据要少我还使用了temp表来简化测试(无需重写,只需注释掉一个连接,它就可以测试了)。因为临时表总是比永久表快。很可能您重写的语句将具有相同的查询计划。重新排列表顺序通常不会产生任何差异。将连接移动到何处几乎不会产生任何差异。临时表并不总是快。优化器知道,从逻辑上讲,连接在何处并不重要ONs和WHERE的连接点分布在一系列内部连接中,它将重新排列它们以进行优化。