SQL 查询花费的时间太长

SQL Query taking WAY too long

我有一个查询花费的时间太长了。

任何列上都没有索引,我很确定 OR 在这方面的行为方式使服务器上的操作变得太难了。

这是我的一个视图,我正在对这个视图进行 SELECT *,需要 4 分钟才能完成。

修改后,我在此视图上执行的查询花费的时间最多。

SELECT * FROM Penny_Assoc_PCB WHERE PRODUCT_ID=68 ORDER BY RECORD_DT, ASSOCIATION_TYPE

/***** 这里是执行计划 *******/ https://www.brentozar.com/pastetheplan/?id=Bki03eIHK

SELECT dbo.synfact_record.RECORD_ID
    ,dbo.synfact_record.PART_ID
    ,dbo.synfact_record.RECORD_DT
    ,dbo.synfact_association.ASSOCIATION_PART_A
    ,dbo.synfact_association.ASSOCIATION_PART_B
    ,dbo.synfact_association.ASSOCIATION_TYPE
    ,dbo.synfact_association.ASSOCIATION_ID
    ,dbo.synfact_record.PRODUCT_ID
FROM dbo.synfact_association
INNER JOIN dbo.synfact_record ON dbo.synfact_association.RECORD_ID = dbo.synfact_record.RECORD_ID
WHERE (
        dbo.synfact_record.PART_ID IN (
            SELECT PART_ID
            FROM dbo.synfact_record AS synfact_record_1
            WHERE (RECORD_STATUS = 1)
                AND (RECORD_TYPE = 0)
            )
        )

    AND dbo.synfact_record.PRODUCT_ID IN(
        8,
        9,
        10,
        15,
        27,
        31,
        34,
        56,
        60,
        61,
        62,
        66,
        67,
        68)
    AND (dbo.synfact_record.RECORD_ID > 499)
    AND (dbo.synfact_record.RECORD_STATUS = 1)
GROUP BY dbo.synfact_record.RECORD_ID
    ,dbo.synfact_record.PART_ID
    ,dbo.synfact_record.RECORD_DT
    ,dbo.synfact_association.ASSOCIATION_PART_A
    ,dbo.synfact_association.ASSOCIATION_PART_B
    ,dbo.synfact_association.ASSOCIATION_TYPE
    ,dbo.synfact_association.ASSOCIATION_ID
    ,dbo.synfact_record.PRODUCT_ID
    ,dbo.synfact_record.RECORD_STATUS

您可以大大简化您的查询。

我已经删除了 GROUP BY,它作为一个没有聚合的巨人 DISTINCT。如果您得到重复项,我建议您在加入时多加考虑。也许您需要更好的加入条件,或者 top-1-per-group.

SELECT r.RECORD_ID,
       r.PART_ID,
       r.RECORD_DT,
       a.ASSOCIATION_PART_A,
       a.ASSOCIATION_PART_B, 
       a.ASSOCIATION_TYPE,
       r.ASSOCIATION_ID,
       r.PRODUCT_ID
FROM
    dbo.synfact_association AS a
INNER JOIN
    dbo.synfact_record AS r ON a.RECORD_ID = r.RECORD_ID
WHERE
       (r.PART_ID IN (
            SELECT PART_ID
            FROM dbo.synfact_record AS r1
            WHERE (r1.RECORD_STATUS = 1)
                AND (r1.RECORD_TYPE = 0)
            )
        )
    AND r.PRODUCT_ID IN
        (8,9,10,15,27,31,34,56,60,61,62,67,68)
    AND (r.RECORD_ID > 499)
    AND (r.RECORD_STATUS = 1);

基于这个查询单独,我会推荐以下索引:

CREATE CLUSTERED INDEX IX_synfact_association_RECORD_ID
  ON synfact_association (RECORD_ID)
-- for non clustered add: INCLUDE (ASSOCIATION_PART_A, ASSOCIATION_PART_B, ASSOCIATION_TYPE)

CREATE CLUSTERED INDEX IX_synfact_record_RECORD_ID
  ON synfact_record (RECORD_STATUS, RECORD_ID)
-- for non clustered add: INCLUDE (PART_ID, RECORD_DT, ASSOCIATION_ID, PRODUCT_ID)

在第二个索引中,可能值得交换 RECORD_IDPART_ID


CREATE NONCLUSTERED INDEX IX_synfact_record_RECORD_TYPE
  ON synfact_record (RECORD_STATUS, RECORD_TYPE, PART_ID)

IN 子句需要最后一个索引