2016-08-18 15 views
5

Tôi đã gặp một số sự cố lạ khi cập nhật Máy chủ MySQL lên phiên bản 5.7 (theo Ubuntu 16.04 LTS).MySQL 5.7 Giảm nhiễu phi thường với thứ tự ASC/DESC trên bảng được phân đoạn

Preambula: Tôi có một số bảng có nhiều bản ghi (~ 250 triệu). Bảng này, trong ngắn hạn, có cấu trúc như vậy:

CREATE TABLE `device_data` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `device` int(11) DEFAULT NULL, 
    `data` double NOT NULL DEFAULT '0', 
    `utc` int(11) NOT NULL DEFAULT '0', 
    PRIMARY KEY (`utc`,`id`), 
    KEY `id` (`id`), 
    KEY `idx_devutc` (`device`,`utc`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 
/*!50100 PARTITION BY RANGE (`utc`) 
(PARTITION y_min VALUES LESS THAN (1200000000) ENGINE = MyISAM, 
PARTITION y_121 VALUES LESS THAN (1210000000) ENGINE = MyISAM, 
PARTITION y_122 VALUES LESS THAN (1220000000) ENGINE = MyISAM, 
... 
... 
... 
PARTITION y_167 VALUES LESS THAN (1670000000) ENGINE = MyISAM, 
PARTITION y_168 VALUES LESS THAN (1680000000) ENGINE = MyISAM, 
PARTITION y_169 VALUES LESS THAN (1690000000) ENGINE = MyISAM, 
PARTITION y_max VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */ 

Vì vậy, tại sao khóa chính không bình thường như vậy (UTC, ID)? Field ID là autoincrement và nó cùng có thể là một khóa chính. Vâng, chúng ta cần phân vùng bảng theo trường UTC và MySQL nói rằng để làm như vậy, trường UTC phải là khóa chính hoặc ít nhất là phần đầu tiên của khóa chính. Chúng tôi không thể sử dụng UTC cùng với khóa chính vì thiết bị có thể gửi dữ liệu nhiều lần trong một giây, vì vậy chúng tôi phải sử dụng khóa chính lạ như vậy: (UTC, ID). Điều này là OK.

Chúng tôi cũng có và lập chỉ mục trên bảng này theo (thiết bị, utc). Tại sao? Vì chúng tôi cần thực thi truy vấn để truy xuất dữ liệu theo một số thiết bị nhất định trong một khoảng thời gian nhất định, ví dụ:

SELECT `utc`, `data` 
FROM `device_data` 
WHERE `device` = :DeviceId AND `utc` >= :UtcFrom AND `utc` < :UtcTo 
ORDER BY `utc`; 

Rất nhanh vì chỉ mục (thiết bị, utc).

Ambula: Sau khi nâng cấp máy chủ MySQL lên phiên bản 5.7 (từ 5.0 hoặc 5.1, tôi không chắc chắn) một số truy vấn trở nên rất chậm (2-3 phút thay vì 100-200 millisesonds). Một số điều tra nhỏ đã tìm thấy một điều kiện: tốc độ truy vấn rơi xuống, khi thứ tự sắp xếp là hậu duệ.

Truy vấn này vẫn còn nhanh (100 milllseconds):

SELECT `utc`, `data` 
FROM `device_data` 
WHERE `device` = :DeviceId AND `utc` >= :UtcFrom AND `utc` < :UtcTo 
ORDER BY `utc` ASC; 

Nhưng truy vấn này là rất chậm (~ 180 giây):

SELECT `utc`, `data` 
FROM `device_data` 
WHERE `device` = :DeviceId AND `utc` >= :UtcFrom AND `utc` < :UtcTo 
ORDER BY `utc` DESC; 

Với các giá trị param cùng, tất nhiên. Theo phiên bản trước của MySQL Server, cả hai truy vấn đều nhanh (100-200 mili giây).

Sau hai ngày làm việc tích cực Tôi tìm thấy một số mẹo để tránh những vấn đề:

SELECT `utc`, `data` 
FROM `device_data` 
WHERE `device` = :DeviceId AND `utc` >= :UtcFrom AND `utc` < :UtcTo 
ORDER BY -`utc` ASC; 

(Attantion vào dấu trừ trước utc trong ORDER BY)

Truy vấn này cũng nhanh chóng, hoàn thiện trong mili giây và trả lại hồ sơ theo thứ tự ngược lại, như chúng ta cần.

Nhưng câu hỏi là:

Câu hỏi: lý do của một hành vi kỳ lạ như MySQL là gì, và làm thế nào tôi có thể sửa chữa nó?

Bạn có ý tưởng nào không?

Cảm ơn.

+0

Bạn có thể kiểm tra xem chỉ mục nào chậm và truy vấn nhanh sử dụng với giải thích? – Shadow

+0

Không có bất ngờ, cả hai đều sử dụng idx_devutc. Hơn nữa, các truy vấn tương tự với trình điều chỉnh 'FORCE INDEX (idx_devutc)' hiển thị cùng một kết quả. – tumick

+0

Không có tệp nào trong phần bổ sung? – Shadow

Trả lời

3

Tôi không phải là nhà phát triển MySQL nên tôi không biết đầy đủ chi tiết.

Tuy nhiên, sau khi battled this on their issue tracker, đoán tốt nhất là đó là một hồi quy do this fix added in 5.7.3:

Phân vùng: Index điều kiện kéo xuống đã không làm việc với các bảng phân vùng. (Bug # 17.306.882, Bug # 70001)

lý thuyết này được nhấn mạnh bởi thực tế là chúng tôi đã có thể phá vỡ các vấn đề bằng cách thiết lập này trong my.cnf:

optimizer_switch=index_condition_pushdown=off

Người ta có thể thử điều này mà không khởi động lại bằng cách sử dụng .

Chúng tôi cũng đã xem xét phương pháp ORDER BY -`utc` ASC nhưng đã sợ hãi vì nó thêm Using filesort vào mỗi kế hoạch thực hiện.

Các vấn đề liên quan