Sql 是否有任何理由将两个视图合并到四倍于它们的组合运行时间

Sql 是否有任何理由将两个视图合并到四倍于它们的组合运行时间,sql,sql-server,optimization,Sql,Sql Server,Optimization,我有两个视图从外部源选择大型数据集。 他们没有做任何计算或聚合,只是一个长select语句 我正在使用 内连接 根据GUID链接两个视图 每个视图中的各个选项如下所示 view1,3:08运行时,检索到174842条记录 view2,0:02运行时,检索到93493条记录 当我加入他们时,我得到了以下信息 Join,14:32运行时,检索到177753条记录 到目前为止,我已经试过了 左连接 右连接 内连接 参加 我尝试过将view1连接到view2,而不是将view2连接到view1。 我尝试

我有两个视图从外部源选择大型数据集。 他们没有做任何计算或聚合,只是一个长select语句

我正在使用

内连接 根据GUID链接两个视图

每个视图中的各个选项如下所示

view1,3:08运行时,检索到174842条记录

view2,0:02运行时,检索到93493条记录

当我加入他们时,我得到了以下信息

Join,14:32运行时,检索到177753条记录

到目前为止,我已经试过了

左连接 右连接 内连接 参加 我尝试过将view1连接到view2,而不是将view2连接到view1。 我尝试调用一个视图,然后在加入另一个视图时从中选择

似乎没有什么影响它

请参考下面的SQL语句

选择 v1.guid, CONVERTDATE,v1.CreatedOn作为CreatedOn, 字段1, 字段2, 字段3, 字段4, 字段5 从…起 视图1 v1 v1.guid=V2.guid上的内部联接视图2 V2 哪里 字段6=‘值’ 这些不是实际的字段名

我得到了预期的结果,只是时间太长了

任何优化帮助都将不胜感激

请尝试以下操作:

SELECT *
INTO #view1
FROM view1

SELECT *
INTO #view2
FROM view2

SELECT
    v1.guid, 
    CONVERT(DATE, v1.CreatedOn) AS CreatedOn,
    field1, 
    field2, 
    field3,
    field4,
    field5
FROM #View1 v1
INNER JOIN #View2 V2 
    ON v1.guid = v2.guid
WHERE
    field6 = 'value'
前两条语句在临时表中具体化了视图数据。如果引擎无法在原始查询中构建良好的执行计划,以上内容应该会有所帮助

如果上述方法没有帮助,请尝试以更好的方式定义主键来定义临时表。大概是这样的:

CREATE TABLE #view1
(
    guid UNIQUEIDENTIFIER PRIMARY KEY
    ....
)

INSERT INTO #view1
SELECT *
FROM view1
因此,通过这种方式,数据应该按GUID排序,从理论上讲,我们应该得到更快的连接

上面提到的可以带来更好的性能,但是我们这里有一个更大的问题-你是通过UNIQUEIDENTIFIER加入的-我知道你可能会看到人们使用它作为主键,但是你会发现通过int或bigint加入更快。如果您需要这样的guid列,以便不在应用程序或其他内容中公开内部ID,这并不意味着您不能使用integer列来执行SQL中的联接

此外,如果无法将数据存储在临时表中的视图中,则可以检查索引视图的创建方式,以及是否可以-存储所需的数据-仅提前应用筛选条件-例如:

INSERT INTO #view1
SELECT *
FROM view1
WHERE field6 = 'value'

因此,现在表的行数减少了,对吗?

结果是,不要在视图中选择100多列,然后从中选择1列!谁会想到,您的两个选项似乎是编译器提示或将结果存储在临时表中。也可以使用索引优化查询,但这需要更多关于视图的知识;它不会运行视图,然后组合结果,因此结果不是线性组合。特别是对于远程查询,优化器很容易无法获得良好的执行计划,并在过滤之前有效地对整个表进行压缩,而不是远程处理联接。您需要深入研究并比较各种查询的执行计划。一个明显的解决方法是在连接之前在临时表中显式选择中间结果。如果这些视图中使用的查询非常简单,那么将查询直接基于这些视图中使用的表可能是值得的。优化器将更容易找到最佳执行计划。但您提到,它们从外部数据源获取数据。因此,使用具有正确索引的临时表在这里可能会更好。是的,我看到很多人在寻找解决方案时谈论索引,但我没有创建任何一个视图,而且我对它们都不太了解,无法开始尝试应用索引。该语句将在视图运行相当快后创建视图,因此我无法使用临时表表,我确实考虑过,但它不是什么应用是邪恶的。只选择您需要的列。我不能使用临时表,也没有构建原始视图,因此我对它们或SQL的了解还不够全面,无法开始索引them@Rob_O按照答案说的去做:遵循必要的步骤,你就会成功fine@AlwaysLearning对最好只具体化所需的行和列。@Rob_O尝试一下,找出问题所在。有时,人们使用返回了大量列的视图,而连接的表只是为了选择部分数据——最终可能会创建视图的简化版本。