Tôi đang làm việc trên một ứng dụng lấy dữ liệu từ nhiều nguồn khác nhau và tạo báo cáo. Hiện tại tôi đang thay đổi nó để thực hiện các báo cáo dựa trên dữ liệu từ một ngày cụ thể trong lịch sử, trước đây nó chỉ hiển thị dữ liệu từ trạng thái hiện tại.BugZilla, cách tốt nhất (nhanh nhất) để nhận trạng thái lỗi (v.v) vào một ngày cụ thể
Một trong những nguồn dữ liệu của tôi là Bugzilla, vì vậy tôi cần lấy dữ liệu Bugzilla cho một ngày nhất định trong lịch sử. Tôi có một kết nối chỉ đọc vào cơ sở dữ liệu Bugzilla nhưng không có cách nào dễ dàng để làm bất cứ điều gì khác với máy chủ (như cài đặt plug-in, hoặc đặt thủ tục trong cơ sở dữ liệu). Ngoài ra, kết nối giữa máy chủ báo cáo và máy chủ Bugzilla chậm, vì vậy tôi muốn thực hiện các phép tính trên máy chủ thay vì tìm nạp dữ liệu và làm việc trên máy chủ báo cáo. Tôi thực sự có điều này làm việc ở một tốc độ chủ yếu chấp nhận được, nhưng tôi không chắc chắn nếu tôi đang làm nó tốt nhất hay 'đúng', tôi lo ngại rằng tốc độ có thể chấm dứt được chấp nhận khi chúng tôi thêm nhiều vấn đề hơn với cơ sở dữ liệu.
Vì vậy, giải pháp của tôi dưới đây - bạn sẽ làm như thế nào.
Đối với một chút nền, Bugzilla lưu trữ trạng thái hiện tại của tất cả các lỗi trong bảng (gọi là 'lỗi') và lịch sử thay đổi cho từng trường trong bảng ('bugs_activity') trông giống như sau:
fieldid INTEGER, -- References the fielddefs table
bug_when TIMESTAMP, -- Time the change happend
added TEXT, -- New text for the field
removed TEXT, -- Old text for the field
Cơ sở dữ liệu Bugzilla là MySQL. Tôi nghĩ rằng đúng cách để làm điều đó là hoặc với một thủ tục lưu trữ hoặc một bảng tạm thời, nhưng tôi không có một trong hai tùy chọn có sẵn cho tôi. Tôi biết cũng có các công cụ báo cáo cho Bugzilla nhưng tôi không có quyền truy cập để cài đặt chúng, cũng là các báo cáo tôi đang tạo dữ liệu liên kết từ các nguồn khác (và có định dạng cụ thể).
Có một cơ sở dữ liệu PostgreSQL cục bộ trên máy chủ báo cáo để tôi có thể định kỳ sao chép tất cả dữ liệu sang đó, nhưng tôi thực sự không muốn làm điều đó vì có vẻ hơi lãng phí khi lưu trữ dữ liệu giống nhau ở hai nơi.
Giải pháp của tôi là tạo bảng trong vùng chọn giống như bảng lỗi thông thường (đối với dữ liệu tôi quan tâm cho một báo cáo nhất định) và sau đó sử dụng tùy chọn này làm nguồn cho lựa chọn bình thường hoạt động giống như truy vấn cho các báo cáo dựa trên dữ liệu ngày nay.
SELECT bug_status, bug_id, op_sys, resolution, rep_platform
FROM (SELECT bug_id,
IFNULL((SELECT removed FROM bugs_activity a, fielddefs f
WHERE a.fieldid = f.id
AND bug_id = b.bug_id AND f.name = 'bug_status'
AND bug_when >= '2012-01-01 00:00:00'
ORDER BY bug_when DESC LIMIT 1), bug_status) AS bug_status,
-- Repeat IFNULL clause for op_sys, resolution and rep_platform
FROM bugs b
WHERE b.creation_ts <= '2012-01-01 00:00:00') bug_subselect
-- Some other filters to reduce the bugs (specific product, ect)
)
-- More filters based on the new values that have been derived
;
Sau đó, tôi sử dụng như là một đầu vào một lựa chọn mà đếm các trạng thái khác nhau, vv
Truy vấn này hóa ra là cách quá chậm, tôi giả sử vì nó nhận được kết quả toàn bộ cho bên trong chọn để nó có thể đặt hàng sau đó và cho tôi cái đầu.
Tôi đã thử làm điều đó bằng cách LEFT THAM GIA bảng bug_activity vào bảng lỗi nhiều lần và sau đó thực hiện truy vấn IFNULL trên các kết quả, nhanh nhưng phức tạp một chút để duy trì trong mã thế hệ để điều chỉnh nó thành điều này:
SELECT bug_status, bug_id, op_sys, resolution, rep_platform
FROM (SELECT bug_id,
IFNULL((SELECT removed FROM bugs_activity a, fielddefs f
WHERE a.fieldid = f.id AND bug_id = b.bug_id AND f.name = 'bug_status'
AND bug_when = (
SELECT MIN(bug_when) FROM bugs_activity a, fielddefs f
WHERE a.fieldid = f.id
AND bug_id = b.bug_id
AND f.name = 'bug_status'
AND bug_when >= '2012-01-01 00:00:00'
LIMIT 1
)
LIMIT 1), bug_status) AS bug_status,
-- Repeat IFNULL clause for op_sys, resolution and rep_platform
FROM bugs b
WHERE b.creation_ts <= '2012-01-01 00:00:00') bug_subselect
-- Some other filters to reduce the bugs (specific product, ect)
)
-- More filters based on the new values that have been derived
;
Bạn cần cả LIMIT 1 trong đó (tôi nghĩ) như một số lĩnh vực đã quản lý để có hai thay đổi trên timestamp cùng (hoặc một trục trặc cơ sở dữ liệu, có thể từ một bản nâng cấp, hoặc hai người dùng chỉnh sửa các lỗi tương tự - - Tôi không chắc chắn, tôi chỉ biết rằng nó ở đó và tôi cần phải giải quyết nó).
Điều này chạy trong khoảng 3 giây mà không có bộ lọc để giảm danh sách lỗi (trường hợp xấu nhất và hầu như không bao giờ xảy ra) và chạy nhanh hơn với bộ lọc. Phiên bản LEFT JOIN chạy ở cùng tốc độ (hơi chậm hơn) vì vậy tôi đã đi với phiên bản trên.OK cho thời điểm này, nhưng tôi có thể thấy nó chậm trong tương lai - Tôi sẽ thêm thông báo tải trong GUI và đã có thông báo cho biết các báo cáo này có thể mất nhiều thời gian hơn để tạo, tôi chỉ tự hỏi nếu tôi ' m thiếu một số mẹo để làm cho nó nhanh hơn.
"Tôi chỉ tự hỏi nếu tôi thiếu một số thủ thuật để làm cho nó nhanh hơn" - vâng. Chúng được gọi là chỉ mục ... –
Bảng bugs_activity không có chỉ mục, hoặc bạn có ý gì đó khác. – SpaceDog
Tôi có nghĩa là chính xác những gì tôi đã nói - chỉ số tăng tốc truy vấn. –