gpt4 book ai didi

sql-server - 全文索引 - 多个表的性能大幅下降

转载 作者:行者123 更新时间:2023-12-02 05:00:19 26 4
gpt4 key购买 nike

我最近一直在学习对我来说非常新的东西 - 全文索引。

似乎我可以针对两个单独的表对相同的参数运行两个单独的查询(使用 CONTAINSTABLE)获得几乎即时的答案(不到 10 毫秒)但是当我将两者组合在一起时,查询需要 1.3 秒 - 或者慢了 130 多倍!!

以下是查询(针对此问题进行了简化)。

查询 1:

SELECT
*
FROM
dbo.FooBar FB
INNER JOIN dbo.FooBalls FBS on FB.ID = FBS.ID
LEFT JOIN CONTAINSTABLE(dbo.FooBar, (Col1, Col2, Col3), @query) FBCONT ON FB.ID = FBCONT.[KEY]
WHERE
FBCONT.[KEY] IS NOT NULL

查询 2:

SELECT
*
FROM
dbo.FooBar FB
INNER JOIN dbo.FooBalls FBS on FB.ID = FBS.ID
LEFT JOIN CONTAINSTABLE(dbo.FooBalls, (Col1), @query) FBSCONT ON FBS.ID = FBSCONT.[KEY]
WHERE
FBSCONT.[KEY] IS NOT NULL

查询组合:

SELECT
*
FROM
dbo.FooBar FB
INNER JOIN dbo.FooBalls FBS on FB.ID = FBS.ID
LEFT JOIN CONTAINSTABLE(dbo.FooBar, (Col1, Col2, Col3), @query) FBCONT ON FB.ID = FBCONT.[KEY]
LEFT JOIN CONTAINSTABLE(dbo.FooBalls, (Col1), @query) FBSCONT ON FBS.ID = FBSCONT.[KEY]
WHERE
(FBCONT.[KEY] IS NOT NULL OR FBSCONT.[KEY] IS NOT NULL)

也许我的研究遗漏了一些东西,但有人能给我一个指标,说明为什么同时使用这两个子句会使性能降低 130 倍以上吗?

注意事项:

  • 我已经检查了用于加入的相关索引是否存在 - 通过各个查询的速度进行了验证。
  • 该过程中实际上涉及更多连接 - 但是它们与正在查询的表完全没有关联,并且在 100,000 多条记录中搜索结果时,响应时间再次低于 10 毫秒。
  • 我尝试用单独的 CONTAINS 语句替换 CONTAINSTABLE - 性能大幅下降,正如我的研究所预期的那样。
  • 已设置目录,仅引用被查询的两个表中的四列
  • @query 参数目前设置为 NVARCHAR (50)。我读到使用 NVACHAR 更快,因为不需要隐式转换。
  • 我知道我可以分别对两个查询执行脏 UNION ALL,但如果可能,我更愿意编写更好的查询而不是将它们组合在一起。此外,如果 @query 值位于链接到一条记录的不同表的两列中,则 UNION ALL 会给我留下潜在的重复项。

我们将不胜感激任何进一步的建议。

最佳答案

您的问题评论表明您通过重写查询的不相关部分(未在问题中显示)将性能提高到令人满意的水平。

如果它有效,这就足够公平了,但并不能解释为什么当查询的其他不相关部分保持不变时,两个单独的查询和合并的查询会有如此显着的不同。

没有看到查询计划和统计结果,很难自信地说;但是,仅基于对 SQL 查询的编写方式的推理,我可以想到两种可能性:

  1. 一个或两个 ID 列(来自 FooBarFooBalls)在之后的行集中可能是非唯一的这两个表已经内部连接。因此,对 CONTAINSTABLE 结果集进行两次而不是一次连接可能会比一次连接“繁殖”更多的记录;较大的结果集需要更长的时间才能传递回客户端并显示。 对此进行测试:比较两个单独查询返回的行数,如果省略 WHERE 子句,则将这些与每个单独查询的行数进行比较。较大的行数通常表示较长的查询运行时间(所有其他条件相同)。

  2. 每个单独的查询都是用左外连接编写的,但结果集随后被限制为仅包含连接成功的行。这实际上是一个内部连接:SQL Server 的查询计划器很可能会识别这个事实并选择一个执行计划,就好像已经指定了一个内部连接一样。相反,组合查询需要其中其中一个 连接(但不一定都成功)成功的行,这是真正的左连接。执行计划可能对这些连接使用不同的、较慢的方法。 对此进行测试:查看执行计划,并与请求的内连接而不是左连接的单独查询的执行计划进行比较。

关于sql-server - 全文索引 - 多个表的性能大幅下降,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16912609/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com