【问题标题】:SQL Performance Issue : Timing OutSQL 性能问题:超时
【发布时间】:2017-09-01 21:31:12
【问题描述】:

在生产环境中执行以下 SQL 查询需要超过 5:19 分钟。此 SQL 是从服务器端 C# 代码动态生成的,并且对于少数客户端需要很长时间才能执行。由于生产时间长,Web 服务超时。您能否优化此 SQL 以提高性能?

这是动态生成的查询 -

SELECT *
  INTO #TepmBase
FROM PFInputDemoV3.dbo.Position_Level_Data_Audit
WHERE PFA_Unique_Identifier = 'TEST_DRILLDOWN_ADVISER'
AND Business_Date BETWEEN '4/1/2017' AND '6/30/2017';

CREATE INDEX IX_TepmBase_ID ON #TepmBase (ID);
CREATE INDEX IX_TepmBase_Audit_Date ON #TepmBase (Audit_Date);

SELECT DISTINCT ID
  INTO #TempBaseDeleted
FROM #TepmBase
WHERE Audit_Date < '8/30/2017 2:09:22 PM'
AND Action LIKE 'Dele%';


SELECT *, ROW_NUMBER() OVER (ORDER BY id) AS RowNumber
  INTO #TepmBaseExtend
FROM (SELECT t.*, ROW_NUMBER() OVER (PARTITION BY t.id ORDER BY Audit_id DESC) AS Rank
  FROM #TepmBase t
  WHERE Audit_Date < '8/30/2017 2:09:22 PM'
    AND NOT Action LIKE 'Dele%'
    AND ID NOT IN (SELECT ID FROM #TempBaseDeleted)
    AND NOT EXISTS (SELECT 1
      FROM #TepmBase
      WHERE Audit_Date BETWEEN '8/30/2017 2:09:22 PM' AND '8/30/2017 2:10:46 PM')) c
WHERE RANK = 1
  AND (ValidatedStatus = 1 OR ValidatedStatus = 3 OR ValidatedStatus = 5
       OR ValidatedStatus = 7 OR ValidatedStatus = 9 OR ValidatedStatus = 11
       OR ValidatedStatus = 13 OR ValidatedStatus = 15 OR ValidatedStatus = 17
       OR ValidatedStatus = 19 OR ValidatedStatus = 21 OR ValidatedStatus = 23
       OR ValidatedStatus = 25 OR ValidatedStatus = 27 OR ValidatedStatus = 29
       OR ValidatedStatus = 31 OR ValidatedStatus = 33 OR ValidatedStatus = 35
       OR ValidatedStatus = 37 OR ValidatedStatus = 39  OR ValidatedStatus = 41
       OR ValidatedStatus = 43 OR ValidatedStatus = 45  OR ValidatedStatus = 47
       OR ValidatedStatus = 49 OR ValidatedStatus = 51  OR ValidatedStatus = 53
       OR ValidatedStatus = 55 OR ValidatedStatus = 57  OR ValidatedStatus = 59
       OR ValidatedStatus = 61 OR ValidatedStatus = 63);



CREATE UNIQUE CLUSTERED INDEX IX_#TepmBaseExtend_RowNumber ON #TepmBaseExtend (RowNumber);

SELECT
  ID,
  PFA_Unique_Identifier,
  Fund_Unique_Identifier,
  Business_Date,
  Information_Date,
  Position_Unique_Identifier,
  Instrument_Group,
  Instrument_Category,
  Instrument_Type,
  Option_Instrument,
  Price,
  Local_Price,
  Quantity,
  LongShort,
  Market_Value,
  Notional_Value,
  Issuer_Counterparty,
  Issuer_Counterparty_Type,
  Issuer_Counterparty_Country,
  Issuer_Counterparty_LegalName,
  Issuer_CounterParty_Affiliate,
  Issuer_Counterparty_Affiliate_Other,
  Investment_Quality,
  Delta,
  Vega,
  DV01,
  IR_Sensitivity_Measure,
  IR_Sensitivity_Measure_Value,
  Strategy,
  Strategy_Name_Other,
  High_Freq_Trading_Indicator,
  Liquidation_Horizon_Days,
  Cleared_by_a_CCP,
  AssetClass_Other,
  Value,
  Exclude_Issuer_Counterparty,
  Exclude_Strategy,
  Exclude_Issuer_Counterparty_Country,
  Symbol,
  Instrument_Description,
  Region,
  Any_Securities_Borrowing_Lending,
  _Highlight
FROM (SELECT
  CAST(b.ID AS bigint) AS ID,
  PFA_Unique_Identifier,
  Fund_Unique_Identifier,
  Business_Date,
  Information_Date,
  Position_Unique_Identifier,
  Instrument_Group,
  Instrument_Category,
  Instrument_Type,
  Option_Instrument,
  Price,
  Local_Price,
  Quantity,
  LongShort,
  Market_Value,
  Notional_Value,
  Issuer_Counterparty,
  Issuer_Counterparty_Type,
  Issuer_Counterparty_Country,
  Issuer_Counterparty_LegalName,
  Issuer_CounterParty_Affiliate,
  Issuer_Counterparty_Affiliate_Other,
  Investment_Quality,
  Delta,
  Vega,
  DV01,
  IR_Sensitivity_Measure,
  IR_Sensitivity_Measure_Value,
  Strategy,
  Strategy_Name_Other,
  High_Freq_Trading_Indicator,
  Liquidation_Horizon_Days,
  Cleared_by_a_CCP,
  AssetClass_Other,
  Value,
  Exclude_Issuer_Counterparty,
  Exclude_Strategy,
  Exclude_Issuer_Counterparty_Country,
  Symbol,
  Instrument_Description,
  CASE
    WHEN ISNULL(Region, '@') = '@' THEN (SELECT TOP 1 PF_Region
      FROM Parameters.dbo.Country_Region_Mapping
      WHERE UPPER(Issuer_Counterparty_Country) = Country_Code)
    ELSE Region
  END AS Region,
  Any_Securities_Borrowing_Lending,
  CASE
    WHEN h.id IS NULL THEN 'N'
    ELSE 'Y'
  END AS _Highlight,
  ROW_NUMBER() OVER (ORDER BY rownumber) AS rn
FROM #TepmBaseExtend b
INNER JOIN (SELECT ID
  FROM #TepmBaseExtend
  WHERE (UPPER(Exclude_Issuer_Counterparty_Country) IN ('NO','N')
         OR Exclude_Issuer_Counterparty_Country IS NULL)
    AND Business_Date = '6/30/2017'
    AND Fund_Unique_Identifier IN
        (SELECT Fund_Unique_Identifier
         FROM PFInputDemoV3..Fund_AUM_Data
         WHERE PFA_Unique_Identifier = 'TEST_DRILLDOWN_ADVISER'
           AND Business_Date = '6/30/2017'
           AND UPPER(Fund_Type) = 'HEDGE')
           AND Fund_Unique_Identifier IN
               (SELECT Fund_Unique_Identifier
                FROM PFInputDemoV3..Fund_Level_Information
                WHERE PFA_Unique_Identifier = 'TEST_DRILLDOWN_ADVISER'
                  AND Business_Date = '6/30/2017')
                  AND Market_Value > 0
                  AND UPPER(Issuer_Counterparty_Country) IN
                      (SELECT DISTINCT Country_Code
                       FROM Parameters.dbo.Country_Region_Mapping
                       WHERE UPPER(PF_Region) = UPPER('Europe_EEA'))) h
  ON h.id = b.id) tmp
WHERE rn BETWEEN 0 AND 100;

DROP TABLE #TepmBase;
DROP TABLE #TepmBaseExtend;
DROP TABLE #TempBaseDeleted;

【问题讨论】:

  • 这不是 MySQL,它没有 ROW_NUMBER()。我猜是 SQL-Server?
  • 没错。 MS SQL 服务器。
  • Stackoverflow 不是优化服务。
  • 上面说了,如果你想聘请我来优化你的代码,我们可以谈谈

标签: sql sql-server performance query-performance query-tuning


【解决方案1】:

这不是查询。这是四个查询。

日期比较看起来很危险。它们仅适用于某些语言设置。生成查询的代码应该是固定的。

至于第二个查询:是否使用索引IX_TepmBase_Audit_Date,取决于DBMS是否认为日期条件限制足够。我想 大部分 记录符合条件,所以我们希望 DBMS 不使用索引。也许Action 上的索引会有所帮助,因为我们正在寻找以特定字符串开头的所有操作。

在您的第三个查询中,您按t.id 进行分区。 id 不应该是表的唯一列吗?可能是主键?分区似乎没有意义,Rank 始终为 1。然后查询包含不相关的 NOT EXISTS 子句。对于所有记录,条件为真或假。这很可能是一个错误。

要使第四个查询快速运行,您需要在#TepmBaseExtend(id) 上建立索引。以及派生表的进一步索引。也许在#TepmBaseExtend(Business_Date, Market_Value, Fund_Unique_Identifier)。不知道您的数据,我不确定究竟是哪个索引,但那个索引可能有效。

【讨论】:

  • 谢谢你,凯特纳。我在第二个和第四个查询中应用了这些索引。它将性能提高了 6 秒。总时间仍然是 5:13 分钟。
  • 有什么办法可以进一步减少执行时间?
  • 所以索引根本没有帮助。无论如何,如前所述,我怀疑您的第三个查询是否正确。您的主要问题可能不是时间,而是要直接查询。
  • 我重新检查了它,看起来查询没问题,并检索到它应该是的正确信息。
  • 嗯,抱歉,我没有线索了。顺便问一下,哪个查询慢?
猜你喜欢
  • 2011-05-21
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
  • 1970-01-01
  • 2017-02-18
  • 2017-10-15
  • 2019-04-13
  • 1970-01-01
相关资源
最近更新 更多