【问题标题】:How can I optimize this query in Firebird 2.1?如何在 Firebird 2.1 中优化此查询?
【发布时间】:2012-03-01 03:47:12
【问题描述】:

我正在使用 Firebird 2.1,我需要一些帮助来优化此查询:(可能通过将 IN-s 替换为 JOINS 或其他方式来加快速度,因为它非常慢)

SELECT ClientID, ClientType, ClientName 
FROM Clients 
WHERE 
    (
        AccessRights = 0 OR 
        OwnerUserID = :uid OR 
        (
            AccessRights = 2 AND 
            ClientID IN (SELECT ClientID 
                            FROM ClientRights 
                            WHERE UserID = :uid)
        )
    ) 
    AND ClientID IN (SELECT CC.ClientID 
                    FROM CaseClients CC 
                    WHERE CC.CaseID IN (SELECT DISTINCT CaseID 
                                        FROM TimeSheet 
                                        WHERE IsBilled = 0) 
                        AND CC.ClientToBill = 1 
                        AND (SELECT BillingType 
                                FROM Cases 
                                WHERE CaseID = CC.CaseID) = 2
    );

谢谢!

【问题讨论】:

  • 您是否已经为要查询的字段添加了索引以加快整个过程?
  • 我不能代表火鸟,但我知道在某些实现中,使用 EXISTS 而不是 IN 更快。
  • 我知道在 SQL Server 中,优化器在使用 AND 谓词时通常比 OR 表现更好,有时可以通过将 OR 转换为逻辑上等效的 AND 来提高性能跨度>

标签: sql optimization join firebird firebird2.1


【解决方案1】:
SELECT ClientID, ClientType, ClientName FROM Clients 
WHERE 
(
    AccessRights = 0 OR 
    OwnerUserID = :uid OR 
    (
        AccessRights = 2 AND 
        EXISTS(SELECT * FROM ClientRights r WHERE r.UserID = :uid and r.ClientId=Clients.ClientID)
    )
) 
AND EXISTS(SELECT * 
                FROM CaseClients CC 
                WHERE 
                CC.ClientID=Clients.ClientID and
                   EXISTS(SELECT * FROM TimeSheet 
                          WHERE IsBilled = 0 and TimeSheet.CaseID=CC.CaseID) 
                    AND CC.ClientToBill = 1 
                    AND EXISTS(SELECT BillingType 
                            FROM Cases 
                            WHERE CaseID = CC.CaseID and BillingType=2)
);

【讨论】:

    【解决方案2】:

    这可能会加快速度,但确保索引正确也会有所帮助..

    SELECT C.ClientID, C.ClientType, C.ClientName 
    FROM Clients C
    INNER JOIN CaseClients CC ON C.ClientID = CC.ClientID AND CC.ClientToBill = 1
    INNER JOIN TimeSheet TS ON CC.CaseID = TS.CaseID AND TS.IsBilled = 0
    INNER JOIN Cases CS ON CC.CaseID = CS.CaseId AND CS.BillingType = 2 
    WHERE AccessRights = 0 
         OR OwnerUserID = :uid 
         OR 
            (
                AccessRights = 2 AND 
                ClientID IN (SELECT ClientID 
                                FROM ClientRights 
                                WHERE UserID = :uid)
            )
        ) 
    

    【讨论】:

      【解决方案3】:
      SELECT DISTINCT
              c.ClientID
             ,c.ClientType
             ,c.ClientName
        FROM Clients c
       INNER JOIN CaseClients cc
          ON c.ClientID = cc.ClientID
       INNER JOIN TimeSheet ts
          ON cc.CaseID = ts.CaseID
       INNER JOIN Cases ca
          ON cc.CaseID = ca.CaseID
       WHERE ts.IsBilled = 0
         AND cc.ClientToBill = 1
         AND ca.BillingType = 2
         AND (c.AccessRights = 0 OR
              c.OwnerUserID = :uid OR
              c.AccessRights = 2 AND c.ClientID IN (SELECT cr.ClientID
                                                      FROM ClientRights cr
                                                     WHERE cr.UserID = :uid)
             )
      

      【讨论】:

        【解决方案4】:

        在我看来,这样会更整洁、更快:

        SELECT  ClientID, ClientType, ClientName 
        FROM    Clients C, CaseClients CC, TimeSheet TS, Cases CA
        WHERE   C.ClientID = CC.ClientID 
        AND CC.CaseID = TS.CaseID 
        AND CC.CaseID = CA.CaseID 
        AND TS.IsBilled = 0
        AND     CC.ClientToBill = 1 
        AND     CA.BillingType = 2 
        AND     (C.AccessRights = 0 OR C.OwnerUserID = :uid OR (C.AccessRights = 2 AND     C.ClientID IN 
        (SELECT ClientID FROM ClientRights WHERE UserID = :uid))) 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-11-15
          • 2017-03-01
          • 2023-04-02
          • 1970-01-01
          相关资源
          最近更新 更多