Sql server 如何强制查询优化程序更有效地处理我的查询?

Sql server 如何强制查询优化程序更有效地处理我的查询?,sql-server,Sql Server,我有一个报告调度系统,其中每个报告都有一组参数,用户会动态地得到提示,然后报告作为SQL代理作业执行,并将输出保存到存档数据库以供以后查看 这一切都很好,但用户希望更改其中一个参数。他们过去常常指定单个成员和位置(这定义了客户),但现在他们希望能够指定多个成员和位置。例如,根据Comet在英国和NI(两个地点)的运营情况,他们可能希望看到Comet在2012年销售额排名前50的产品 我的报告过去需要几秒钟才能运行,但经过这次更改,现在大约需要8分钟 当报表调度器拾取报表请求时,它将成员/位置列表

我有一个报告调度系统,其中每个报告都有一组参数,用户会动态地得到提示,然后报告作为SQL代理作业执行,并将输出保存到存档数据库以供以后查看

这一切都很好,但用户希望更改其中一个参数。他们过去常常指定单个成员和位置(这定义了客户),但现在他们希望能够指定多个成员和位置。例如,根据Comet在英国和NI(两个地点)的运营情况,他们可能希望看到Comet在2012年销售额排名前50的产品

我的报告过去需要几秒钟才能运行,但经过这次更改,现在大约需要8分钟

当报表调度器拾取报表请求时,它将成员/位置列表存储在表中,然后链接到报表中。这似乎是出问题的地方

以下是报告的开头(这足以解决性能问题):

如果我在ProductList CTE中添加一个过滤器,例如

AND MemberId = 163
然后又回到了几秒钟而不是几分钟。MemberId=163是我为其运行报告的成员,在本例中,它们只具有一个位置

我最初试过这个:

    ProductList AS (
        SELECT DISTINCT
            pw.ProductId,
            pw.WeightSource,
            m.MaterialId
        FROM
            MemberList ml
            INNER JOIN PackagingWeightDerivedBase pw ON pw.MemberId = ml.MemberId
            INNER JOIN Material m ON m.ExtendedMaterialId = pw.ExtendedMaterialId
        WHERE
            ISNULL(@LevelId, pw.LevelId) = pw.LevelId
            AND ISNULL(@MaterialId, m.MaterialId) = m.MaterialId)
…但这更慢,我离开了30分钟,它从未完成。此外,这在任何情况下都不是严格正确的,因为它会为成员/位置筛选器中的每一行返回重复的结果

所以我知道问题在于,乐观主义者没有理智地处理这个问题。基本上它有:

Report.ReportMemberLocation - 1 row
Material - about 50 rows
PackagingWeightDerivedBase - millions of rows
…而且当它发现数据属于不同的成员时,它一定会抽出数百万行数据,仅仅为了扔掉其中99.99%的数据


是否有其他方法可以表达此查询,以强制优化者首先按成员列表过滤权重表?或者可能是我遗漏了什么提示?

你可以用(index=index\u NAME)放一个
在其中一个表强制它使用该索引之后,问题是PackageWeightDerivedBase实际上是一个视图,这就是我需要添加索引的地方。在花了整整一天的时间来处理这个问题之后,我决定唯一明智的方法是添加一个规则,一次只能添加一个成员包括。这相当好,因为我可以在WHERE子句中直接使用成员,性能恢复正常,用户也很高兴,因为他们仍然可以在一次点击中跨多个位置运行报告。
Report.ReportMemberLocation - 1 row
Material - about 50 rows
PackagingWeightDerivedBase - millions of rows