SQL Server JOIN使用大表执行速度非常慢

时间:2016-01-27 17:49:40

标签: sql sql-server

下面我有一个查询,它从一个表中接收一封电子邮件,并加入另外三个表来匹配该电子邮件。它还会按两列(.example1, .example2 { color: #646464; } utm_campaign)进行过滤,以确保它们不为空。

其中两个表有近百万行,另外两个表约有100,000行。

目前,要输出100行,大约需要60秒。 我预计此utm_source语句将输出500,000-1,000,000行,这可能需要4-5天才能完成。

我不明白为什么服务器的处理器只使用了27%的资源,或者我可以用JOIN做不同的事情来使这个过程变得更快。我尽可能地改进了JOIN,并且增加了服务器上的处理器数量无济于事。我对索引编制并不熟悉,我也不知道可以对大部分数据进行编制。

有没有人有过在这么大的表上做JOIN的经验,可以识别我的查询逻辑中的缺陷,或者想出一种更有效的方法来匹配其他表中的行。请参阅下面的完整查询以供参考:

SELECT

2 个答案:

答案 0 :(得分:1)

让我们从现实检查开始。这将有助于你的发展:

  

其中两个表有近百万行,其他两个表都在附近   100,000行。

好。哪里大?大约20年前,当我开始使用SQL Server - 4.21时,一百万行很小。今天,除非该联接中的每个表都有十亿行或更多,否则不要说大。

这很慢,因为代码错误,数据库设计可能不好。不是因为SQL Server不好。

  

我不明白为什么服务器的处理器只使用其中的27%   资源,

什么资源?通常,SQL Server(一般来说是数据库服务器)受到磁盘IO或内存的限制,因为大多数小型商店都会让它们缺乏内存,很少投资于合适的磁盘子系统。 CPU很少忙,因为光盘无法跟上。等待加载数据时很难处理。数据库服务器移动到所有SSD设置多年的原因 - 更便宜,因为SSD比光盘快数百倍。

你加入的问题是 - 他们很糟糕。非常糟糕。

  • 您根本不使用标准连接语法。加入并选择。查找连接的正确语法。

  • 您的比较过于复杂 - 或者在加载数据库时有人不理解Null的值。此连接应该只需要每个表一个条件。不是2.

  • 您真的通过电子邮件地址加入吗?这是超级糟糕的数据库设计。应该有一个包含电子邮件地址的表,所有其他表应该有一个数字的外键。

通常 - 您还需要查看您的查询计划(您在此处发布)以查看SQL Server如何处理它。你在桌子上有适当的指数吗?不想过于消极,但看起来设计数据库的人并没有太多的知识 - 所以我很有可能它错过了必要的指数,这迫使全表扫描。查询计划会告诉你。如果是这种情况,请确保添加必要的索引。如果是这种情况 - 认为自己很幸运,因为一旦添加了指数,业绩就会大幅增加。

答案 1 :(得分:1)

在VP.email,SCU.email,SCH.cust_id和GF.email上创建索引。

在您正在计算的三个连接上反转连接逻辑,例如PU.email ='“'+ VP.email +'”'=> VP.email = SUBSTRING(PU.email,2,LEN(PU.email) - 2)。

您的过滤器可能可以播放,但这有点棘手。我认为VP.utm_source不是NULL而VP.utm_source!=''=> VP.utm_source> '',您可以在VP.utm_source上创建索引,但只有在只填充了几行时才会使用它。您还可以将其作为辅助列添加到VP.email上的索引。我认为这部分是你的问题中较小的一部分。上面的联接很可能是你最大的问题。