Sử dụng tổng số trên tổng hợp để cải thiện hiệu suất


7

Tôi có hai bảng: chi tiết và tổng số các chi tiết này.

Chi tiết ( Giải pháp chậm ):

select 
    OrderId             =   r.OrderId                   
  , TotalQty            =   SUM(r.Quantity)
  , TotalGrossConsid    =   SUM(r.Price * r.Quantity)
from dbo.Order r
group by r.OrderId

Tổng cộng ( Giải pháp nhanh ):

select 
    t.OrderId                           
  , t.TotalQty          
  , t.TotalGrossConsid  
  , t.IsValid
from dbo.OrderTotal t

Đôi khi tổng số trở nên không hợp lệ (một số công việc phải tính toán lại tổng số thay đổi nhưng nó bị trì hoãn). Khi bạn hiểu truy vấn thứ hai nhanh hơn và số lượng tổng hợp lệ nhiều hơn thì không hợp lệ. Vì vậy, tôi đang tìm kiếm một truy vấn kết hợp trả về tổng số hợp lệ từ bảng thứ hai (tổng) và trả về tổng số được tính toán lại động bằng cách sử dụng truy vấn chậm đầu tiên. Vì vậy, mục tiêu của tôi sẽ đạt được: tất cả các tổng số là hợp lệ và thời gian để phản hồi nhanh hơn sau đó tính toán lại đầy đủ.

Đây là nỗ lực của tôi ( Giải pháp lai ):

with fast_static(OrderId, TotalQty, TotalGrossConsid, IsValid)
as
(
    select 
        t.OrderId                           
      , t.TotalQty          
      , t.TotalGrossConsid  
      , t.IsValid
    from dbo.OrderTotal t
)

, slow_dynamic(OrderId, TotalQty, TotalGrossConsid)
(
   select 
        OrderId             =   r.OrderId                   
      , TotalQty            =   SUM(r.Quantity)
      , TotalGrossConsid    =   SUM(r.Price * r.Quantity)
    from dbo.Order r
)
select
    OrderId, TotalQty, TotalGrossConsid
from fast_static 
where IsValid = 1  
union all
select
  OrderId, TotalQty, TotalGrossConsid 
from slow_dynamic s 
    --inner join fast_static ff
    --on ff.OrderId = s.OrderId 
where   --ff.Valid = 0 -- too slow!!!
    s.OrderId in (select OrderId from fast_static f where f.Valid = 0)

Tôi đã so sánh giải pháp Nhanh và kết hợp một, tôi nhận được 32% đến 68% (chi phí truy vấn tương đối). Nếu bạn có thể thấy biến thể nhận xét, nó bằng 1% đến 99% (quá tệ). Có thể cải thiện truy vấn này?

THÊM

@gbn:

Valid  =  case when i.OrderId is null then 1 else 0 end
...
dbo.OrderTotal t  left join dbo.InvalidOrders i

Có, tôi có một công việc để tính toán lại tổng số và quá trình này không được đồng bộ hóa với các yêu cầu truy vấn. Các bảng không hợp lệ là một bảng nhỏ lưu trữ các bản ghi để biết rằng tổng số không hợp lệ (được tính toán lại)

GIẢI PHÁP

Quan điểm được lập chỉ mục là sự lựa chọn tốt nhất. Lưu ý về phiên bản SQL Server ( gợi ý không giới hạn cho các phiên bản không dành cho doanh nghiệp) và sẵn sàng tạo lại một số đối tượng cơ sở dữ liệu ( SET ANSI_NULLS ON, SET QUOTED_IDENTIFIER ON) để bắt đầu sử dụng các khung nhìn được lập chỉ mục ở phía máy khách.


Vì vậy, bạn có một công việc mà tính trước tổng số? Cờ IsValid nói gì? Bạn có bao nhiêu hàng, bạn có chỉ mục, lược đồ bảng là gì?
gbn

Vì vậy, OrderTotal là một chế độ xem với TRÁI PHIẾU? Hoặc đây là mã bạn sử dụng để tạo INSERT / UPDATE cho OrderTotal? Những lược đồ abozut + chỉ mục quá? Đừng ẩn thông tin ...
gbn

@gbn Tôi đã thêm một số ý kiến ​​cho câu hỏi của tôi. Đơn hàng, OrderTotals, UnlimitedOrder: Một số mã thay đổi chi tiết đơn hàng và đưa bản ghi vào UnlimitedOrder. Một số công việc tính toán lại tổng số dựa trên UnlimitedTotals và xóa bản ghi khỏi UnlimitedOrder. Một số truy vấn mã tổng cộng. Đây là các quá trình như là.
garik

@garik: bạn không nên cần UnlimitedOrder: đây là một bản hack cho lập chỉ mục kém hoặc thiết kế kém.
gbn

@gbn - đơn hàng có lẽ có thể có một số details. Đây có vẻ như là một vấn đề OLAP đối với tôi - các tổng hợp được tính toán trước để cải thiện hiệu năng truy vấn trong
kho dữ liệu

Câu trả lời:


5

Tôi không thể hiểu tại sao bạn không thể tổng hợp một cách nhanh chóng và tại sao nó quá chậm. Ý tưởng "Hợp lệ" có phải là cách giải quyết để xử lý độ trễ của OrderTotals hoặc một số quy trình kinh doanh không

Cả hai ý tưởng này đều loại bỏ bảng UnlimitedOrder, một cách giải quyết cho việc lập chỉ mục kém.

  • Gợi ý 1:

Tạo một cột được tính toán

ALTER TABLE dbo.Order ADD PriceXQuantity AS Price * Quantity PERSISTED

Thêm một chỉ mục

CREATE INDEX IX_Totals ON dbo.Order (OrderID) INCLUDE Quantity, PriceXQuantity)

Xem những gì xảy ra

  • Gợi ý 2:

Sử dụng chế độ xem được lập chỉ mục

CREATE VIEW OrderTotals
WITH SCHEMABINDING
AS
select 
    OrderId             =   r.OrderId                   
  , TotalQty            =   SUM(r.Quantity)
  , TotalGrossConsid    =   SUM(r.Price * r.Quantity)
  , COUNT_BIG(*) AS Dummy
from dbo.Order r
group by r.OrderId
GO
CREATE UNIQUE CLUSTERED INDEX IXCU_OrderTotals ON OrderTotals (OrderId9
GO

Bạn cũng có thể sử dụng cột được tính toán ở đây


1) Do một số mã phía máy khách yêu cầu TẤT CẢ tổng số. 2) Vì có quá nhiều bản ghi mỗi giây chèn vào bảng chi tiết. Bạn vẫn nghĩ rằng chế độ xem được lập chỉ mục (hoặc trường được tính toán lại) sẽ không quá chậm (reindexing, tái tạo chế độ xem hoặc một cái gì khác)? Tôi nghĩ đó là một câu hỏi lớn. Thay đổi suy nghĩ của tôi.
garik

@garik: Tôi có 40.000 hàng mỗi giây. Tôi có tổng hợp trên cùng một bảng trong thời gian thực quá.
gbn

Bạn đúng rồi! Chế độ xem được lập chỉ mục là một cái gì đó tuyệt vời. Cảm ơn bạn vì ví dụ thực tế (... 40.000). Làm xong.
garik

2
@gbn - Đó là một tính năng khá thú vị, là chế độ xem được lập chỉ mục luôn đồng bộ với các bảng cơ sở hay nó có làm mới khi bạn cam kết không?
Jack nói hãy thử topanswers.xyz

2
@garik: Tôi có xu hướng luôn sử dụng nó (ngay cả trên Enterprise): Tôi đã thấy SQL Server frankyl khá bản lĩnh khi sử dụng các chế độ xem được lập chỉ mục đôi khi. Bạn cũng có thể bao bọc chế độ xem được lập chỉ mục trong một chế độ xem khác không có giới hạn vì gợi ý propogate "vào trong": vì vậy không cần trong chế độ xem bên ngoài của bạn
gbn

2

Nếu chi phí sẽ không quá cao, bạn có thể xem xét chuyển IsValidcờ vào Detailbảng và lập chỉ mục không? Điều này sẽ làm chậm các giao dịch của bạn nhưng cải thiện hiệu năng truy vấn vì Detailbảng lớn (có lẽ) sẽ được truy cập trong một bảng lớnrange scan

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.