Xử lý database WordPress chậm một cách an toàn
Nhiều site WordPress chậm ở database từ rất lâu trước khi chậm ở bất kỳ nơi nào khác. Plugin tích tụ, bảng options phình to, và một template đơn lẻ có thể âm thầm bắn ra hàng trăm truy vấn. Tin tốt là việc điều tra có phương pháp rõ ràng. Hướng dẫn này nói về cách tìm các truy vấn tốn kém, các nguyên nhân thường gặp, và các cách sửa được sắp xếp từ ít rủi ro nhất đến nhiều rủi ro nhất.
Bắt đầu bằng việc tìm vài truy vấn thực sự quan trọng
Cài Query Monitor trên một bản staging và tải trang chậm khi đang đăng nhập với tư cách quản trị viên. Một bài viết của Stack Harbor mô tả trường hợp một trang admin tạo ra 800 truy vấn nhưng chỉ năm truy vấn chiếm phần lớn thời gian, khớp với kinh nghiệm thông thường: phần đuôi dài chỉ là nhiễu. Hãy dùng các chế độ xem sau:
- Queries by component cho thấy plugin hoặc theme nào tốn nhiều thời gian truy vấn nhất.
- Queries by caller nêu tên hàm, hữu ích khi component chỉ là core.
- Slowest queries: cả hai nguồn chúng tôi đọc đều coi mọi thứ trên khoảng 50 ms là đáng xem xét, và bài của Stack Harbor gọi trên 200 ms là mục tiêu rõ ràng.
- Duplicate queries mỗi truy vấn là một cơ hội cache bị bỏ lỡ.
Trên server production nơi bạn không thể cài plugin debug, MySQL slow query log là phương án thay thế. Ngưỡng thấp ghi lại nhiều chi tiết hơn, nhưng lưu ý rằng ngưỡng nửa giây sẽ bỏ sót các thủ phạm chậm vừa phải, nên đừng kết luận database khỏe chỉ vì log im lìm.
# my.cnf (illustrative values)
slow_query_log = 1
long_query_time = 0.5
log_queries_not_using_indexes = 1
Ba dạng vấn đề
Nhiều truy vấn nhỏ (mẫu N+1)
Đọc post meta bên trong một vòng lặp có thể tạo một truy vấn cho mỗi post. Nạp trước (prime) meta cache cho cả danh sách sẽ biến nó thành một truy vấn. WP_Query thường tự prime giúp bạn, nên vấn đề này chủ yếu xảy ra với mã tùy biến tắt cache hoặc tự dựng danh sách ID.
$ids = wp_list_pluck( $items, 'ID' );
update_meta_cache( 'post', $ids );
foreach ( $items as $item ) {
$price = get_post_meta( $item->ID, '_price', true ); // served from cache
}
Một truy vấn chậm
Thường là thiếu index, hay gặp ở bảng do plugin tạo ra. Các bảng core đi kèm index hợp lý; bảng của plugin đôi khi không có. Hướng dẫn của WP Engine minh họa vì sao điều này quan trọng bằng một truy vấn mất 20 ms với 10.000 dòng nhưng khoảng 2 giây với một triệu dòng. Nó cũng cảnh báo mỗi index tiêu tốn dung lượng và làm chậm thao tác ghi, nên hãy thử trên staging, đo trước và sau, và giữ kế hoạch rollback. Với đa số chủ site, bước thực tế là báo truy vấn chậm cho tác giả plugin hoặc nhà cung cấp hosting.
Cùng một truy vấn lặp lại
Nếu một truy vấn giống hệt chạy hàng chục lần mỗi request, object cache là cách sửa. WP Engine gọi persistent object caching, với Redis hoặc Memcached, thường là cải thiện đơn lẻ lớn nhất, vì các request lặp lại bỏ qua database và transient nằm trong bộ nhớ thay vì bảng options.
Autoloaded options
Autoloaded option được lấy ở mọi request. Những phần còn sót lớn từ các plugin đã gỡ là gánh nặng kinh điển. WordPress 6.6 đã đổi cách này hoạt động: ghi chú dành cho developer của core giải thích rằng các option không yêu cầu autoload tường minh sẽ không còn được autoload nếu giá trị của chúng vượt quá 150.000 byte, và Site Health hiển thị cảnh báo nghiêm trọng khi tổng dữ liệu autoload vượt quá 800 KB. Ghi chú cũng nói các dòng mới có thể dùng các giá trị như on, off, auto, auto-on và auto-off, nên SQL cũ chỉ kiểm tra yes sẽ bỏ sót các mục.
SELECT option_name, LENGTH(option_value) AS bytes
FROM wp_options
WHERE autoload IN ('yes', 'on', 'auto', 'auto-on')
ORDER BY bytes DESC
LIMIT 20;
Hãy điều chỉnh tiền tố bảng cho phù hợp với bản cài của bạn. Ghép từng dòng lớn với plugin của nó. Dữ liệu từ các plugin đã xóa nhìn chung an toàn để dọn sau khi sao lưu; dữ liệu từ plugin đang hoạt động sẽ chỉ bị ghi lại, nên hãy xử lý chính plugin đó.
Transient và revision
Core xóa các transient hết hạn theo lịch hằng ngày, nhưng phần còn sót vẫn tích tụ: những transient được lưu không có thời hạn sẽ không bao giờ được dọn, WP-Cron chỉ chạy khi có khách truy cập, và một số plugin đặt dữ liệu giống cache vào bảng options. Bài viết của WP Engine cũng nêu một điểm tỉnh táo về revision: xóa 40.000 revision có thể giải phóng 300 MB nhưng thay đổi rất ít thời gian tải trang, vì các dòng đó không được đọc trong các lượt xem trang thông thường. Nó vẫn có ích cho backup và migration, nhưng đừng kỳ vọng phép màu về tốc độ.
Quy tắc an toàn
- Sao lưu và thử khôi phục trước khi xóa bất cứ thứ gì.
- Thực hiện thay đổi trên staging trước và mỗi lần chỉ đổi một thứ.
- Đo lại sau mỗi bản sửa; đừng bắt đầu bản tiếp theo cho đến khi bản trước đã được xác minh.
- Dùng một plugin dọn dẹp, đừng dùng nhiều.
OPTIMIZE TABLEchủ yếu là công cụ thu hồi dung lượng trên InnoDB hơn là công cụ tăng tốc.- Lời khuyên bật MySQL query cache đã lỗi thời, vì nó đã bị loại bỏ từ MySQL 8.0.
Với cửa hàng WooCommerce, bài của Stack Harbor cũng chỉ ra các bảng Action Scheduler phình to và High-Performance Order Storage là những mục cần xem xét. Nếu trang admin hoặc checkout của site bạn đang ì ạch, dịch vụ của chúng tôi bao gồm rà soát database và truy vấn, và các theme của chúng tôi được xây dựng để tránh các truy vấn không cần thiết ở front end.