Cải thiện hiệu suất chọn CASE


7

Tôi có truy vấn sau đây mất tới 2 giây để chạy trên tập dữ liệu có ít hơn 100K hàng.

SQL của tôi rất hoen gỉ nhưng điều này có vẻ như nó đang làm rất nhiều việc hơn bình thường. Bất cứ ai cũng có thể cung cấp một số gợi ý về nơi để tìm cách tăng tốc độ này?

SELECT
    a.AddressID,
    IsPrincipal = CASE
    WHEN EXISTS(SELECT TOP 1 1 FROM dbo.Setting s WHERE s.SettingValue = a.AddressID AND s.SettingDefinitionID = 3 AND s.ProfileID = 1)
                THEN 1
                ELSE 0
            END,
    IsPickUp = CASE
                WHEN EXISTS(SELECT TOP 1 1 FROM dbo.AddressRole ar WHERE ar.AddressID = a.AddressID AND ar.[AddressRoleTypeID] = 2)
                THEN 1
                ELSE 0
            END,
    IsSender = CASE
                WHEN EXISTS(SELECT TOP 1 1 FROM dbo.AddressRole ar WHERE ar.AddressID = a.AddressID AND ar.[AddressRoleTypeID] = 3)
                THEN 1
                ELSE 0
            END,
            IsDelivery = CASE
                WHEN EXISTS(SELECT TOP 1 1 FROM dbo.AddressRole ar WHERE ar.AddressID = a.AddressID AND ar.[AddressRoleTypeID] = 4)
                THEN 1
                ELSE 0
            END,
    IsReceiver = CASE
                WHEN EXISTS(SELECT TOP 1 1 FROM dbo.AddressRole ar WHERE ar.AddressID = a.AddressID AND ar.[AddressRoleTypeID] = 5)
                THEN 1
                ELSE 0
            END
        FROM dbo.[Address] AS a
        WHERE a.MFTID = '12345'

Câu trả lời:


7

Thay vì thực hiện tra cứu như vậy cho mỗi hàng, bạn có thể tham gia AddressRoleSettingcác bảng như thế này:

SELECT
    a.AddressID,
    IsPrincipal = Max(iif(s.SettingValue Is Not Null, 1, 0)),
    IsPickUp = Max(iif(ar.AddressRoleTypeID = 2, 1, 0)),
    IsSender = Max(iif(ar.AddressRoleTypeID = 3, 1, 0)),
    IsDelivery = Max(iif(ar.AddressRoleTypeID = 4, 1, 0)),
    IsReceiver = Max(iif(ar.AddressRoleTypeID = 5, 1, 0))
  FROM dbo.[Address] AS a
  Left Join dbo.Setting As s
    On a.AddressID = s.SettingValue
    And s.SettingDefinitionID = 3
    And s.ProfileID = 1
  Left Join dbo.AddressRole As ar
    On a.AddressID = ar.AddressID
  WHERE a.MFTID = '12345'
  Group By a.AddressID;

Điều này sẽ làm giảm số lượng các phép nối được thực hiện và không thay đổi số lượng thẻ của tập kết quả.

Tôi đã thêm vào MAXđể tôi có thể làm một GROUP BY, vì tôi hoàn toàn mong đợi rằng có thể có nhiều hơn một hàng trong AddressRolebảng cho mỗi hàng trong Addressbảng. Bằng cách này, chúng tôi duy trì số lượng thẻ giống như Addressbảng, nhưng chúng tôi có thể xem liệu có bất kỳ hàng nào trong AddressRolegiá trị chứa giá trị AddressRoleTypeIDmà chúng tôi đang tìm kiếm không.

Các MAXGROUP BYkhông cần thiết nếu các truy vấn con của truy vấn ban đầu của bạn mà không TOPtrả về một hàng duy nhất.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.