Tôi chỉ thiết lập một hệ thống ghi nhật ký bao gồm nhiều bảng có cùng bố cục.
Có một bảng cho mỗi nguồn dữ liệu.
Đối với người xem nhật ký, tôi muốn
- UNION tất cả các bảng nhật ký ,
- lọc chúng bằng tài khoản ,
- thêm một cột giả để xác định nguồn,
- sắp xếp chúng theo thời gian ,
- và giới hạn chúng để phân trang .
Tất cả các bảng có chứa một trường được gọi zeitpunkt
là cột ngày / thời gian được lập chỉ mục.
Nỗ lực đầu tiên của tôi là:
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt AS zeit,
'hp' AS source FROM is_log AS l WHERE l.account_id = 730)
UNION
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt,
'ig' AS source FROM ig_is_log AS l WHERE l.account_id = 730)
ORDER BY zeit DESC LIMIT 10;
Trình tối ưu hóa không thể sử dụng các chỉ mục ở đây vì tất cả các hàng từ cả hai bảng được trả về bởi các truy vấn con và được sắp xếp sau UNION
.
Cách giải quyết của tôi là như sau:
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt AS zeit,
'hp' AS source FROM is_log AS l WHERE l.account_id = 730
ORDER BY l.zeitpunkt DESC LIMIT 10)
UNION
(SELECT l.id, l.account_id, l.vnum, l.count, l.preis, l.zeitpunkt,
'ig' AS source FROM ig_is_log AS l WHERE l.account_id = 730
ORDER BY l.zeitpunkt DESC LIMIT 10)
ORDER BY zeit DESC LIMIT 10;
Tôi đã mong đợi công cụ truy vấn sẽ sử dụng các chỉ mục ở đây vì cả hai truy vấn con nên được sắp xếp và giới hạn trước UNION
đó, sau đó hợp nhất và sắp xếp các hàng.
Tôi thực sự nghĩ rằng đây sẽ là nó, nhưng chạy EXPLAIN
trên truy vấn cho tôi biết các truy vấn con vẫn tìm kiếm cả hai bảng.
EXPLAINing
bản thân các truy vấn con cho tôi thấy sự tối ưu hóa mong muốn nhưng UNIONing
chúng không thực hiện được.
Tôi đã bỏ lỡ một cái gì đó?
Tôi biết rằng ORDER BY
các mệnh đề trong UNION
các truy vấn con được bỏ qua mà không có a LIMIT
, nhưng có một giới hạn.
Chỉnh sửa:
Trên thực tế, có lẽ cũng sẽ có các truy vấn mà không cóaccount_id
điều kiện.
Các bảng đã tồn tại và chứa đầy dữ liệu. Có thể có những thay đổi trong cách bố trí tùy thuộc vào nguồn nên tôi muốn chia chúng. Ngoài ra, các khách hàng đăng nhập sử dụng các thông tin khác nhau vì một lý do.
Tôi phải giữ một loại lớp giữa các trình đọc nhật ký và các bảng thực tế.
Dưới đây là các kế hoạch thực hiện cho toàn bộ truy vấn và truy vấn con đầu tiên cũng như cách bố trí bảng chi tiết:
UNION DISTINCT
? Không cần thiết phải sắp xếp và phân biệt ở đó, vì kết quả sẽ khác nhau giữa các truy vấn con, do cột nhận dạng phụ. Sử dụng UNION ALL
.
source
cột? Bằng cách này, bạn có thể tránh UNION
s và sử dụng (các) chỉ mục trên tất cả dữ liệu của mình.
UNION ALL
mang lại kế hoạch thực hiện khác nhau.
(account_id, zeitpunkt)
. Bạn có một chỉ số như vậy? Điều tốt nhất thứ hai sẽ là (tôi nghĩ) đơn(zeitpunkt)
- nhưng hiệu quả nếu điều đó được sử dụng phụ thuộc vào tần suấtaccount_id=730
xuất hiện của các hàng .