Bạn chỉ nên vô hiệu hóa bộ đệm truy vấn với
[mysqld]
query_cache_size = 0
và sau đó khởi động lại mysql. Tại sao tôi lại đề nghị như vậy ???
Cache truy vấn sẽ luôn đối đầu với InnoDB. Sẽ thật tuyệt nếu MVCC của InnoDB sẽ cho phép các truy vấn được cung cấp từ bộ đệm truy vấn nếu các sửa đổi không ảnh hưởng đến các lần đọc lặp lại cho các giao dịch khác. Thật không may, InnoDB không làm điều đó. Rõ ràng, bạn có rất nhiều truy vấn bị vô hiệu hóa khá nhanh và có thể không được sử dụng lại.
Đối với InnoDB trong MySQL 4.0, bộ đệm truy vấn đã bị vô hiệu hóa cho các giao dịch. Đối với MySQL 4.1+, InnoDB đóng vai trò cảnh sát giao thông khi cho phép truy cập vào bộ đệm truy vấn trên cơ sở mỗi bảng.
Từ góc độ câu hỏi của bạn, tôi sẽ nói rằng việc biện minh cho việc xóa bộ đệm truy vấn không phải là quá nhiều chi phí, mà là cách InnoDB quản lý nó.
Để biết thêm thông tin về cách InnoDB tương tác với bộ đệm truy vấn, vui lòng đọc trang 213-215 của cuốn sách "MySQL hiệu suất cao (Ấn bản thứ hai)" .
Nếu tất cả hoặc phần lớn dữ liệu của bạn là MyISAM, bạn có thể đi với ý tưởng ban đầu của mình về việc sử dụng SQL_NO_CACHE.
Nếu bạn có sự kết hợp của InnoDB và MyISAM, bạn sẽ phải tìm sự cân bằng phù hợp cho ứng dụng của mình dựa trên mức độ sai sót của bộ nhớ cache. Trên thực tế, các trang 209-210 của cùng một cuốn sách chỉ ra những lý do khiến bộ nhớ cache bị mất:
- Truy vấn không được lưu trong bộ nhớ cache, bởi vì nó chứa cấu trúc không xác định (chẳng hạn như CURRENT_DATE) hoặc do tập kết quả của nó quá lớn để lưu trữ. Các loại truy vấn không thể kiểm soát được làm tăng biến trạng thái Qcache_not_cached.
- Máy chủ chưa bao giờ thấy truy vấn trước đó, vì vậy nó không bao giờ có cơ hội lưu trữ kết quả của nó.
- Kết quả của truy vấn đã được lưu trữ trước đó, nhưng máy chủ đã xóa nó. Điều này có thể xảy ra vì không có đủ bộ nhớ để giữ nó, bởi vì ai đó đã hướng dẫn máy chủ xóa nó hoặc vì nó không hợp lệ
và nguyên nhân gốc của lỗi bộ nhớ cache cao với một vài truy vấn không thể truy cập có thể là:
- Bộ đệm truy vấn chưa ấm. Đó là máy chủ chưa có cơ hội lấp đầy bộ đệm với các tập kết quả.
- Máy chủ đang nhìn thấy các truy vấn mà nó chưa từng thấy trước đây. Nếu bạn không có nhiều truy vấn lặp đi lặp lại, điều này có thể xảy ra ngay cả khi bộ đệm được làm nóng.
- Có rất nhiều mất hiệu lực bộ nhớ cache.
CẬP NHẬT 2012-09-06 10:10 EDT
Nhìn thông tin cập nhật mới nhất của bạn, bạn đã query_cache_limit
đặt thành 1048576 (1M). Điều này giới hạn bất kỳ kết quả nào được đặt thành 1M. Nếu bạn lấy bất cứ thứ gì lớn hơn, đơn giản là nó sẽ không được lưu trữ. Mặc dù bạn đã query_cache_size
đặt thành 104857600 (100M), nhưng điều này chỉ cho phép 100 kết quả được lưu trong bộ nhớ cache trong một thế giới hoàn hảo. Nếu bạn thực hiện hàng trăm truy vấn, phân mảnh sẽ xuất hiện khá nhanh. Bạn cũng có 4096 (4K) làm tập kết quả kích thước tối thiểu. Thật không may, mysql không có cơ chế nội bộ để chống phân mảnh bộ đệm truy vấn.
Nếu bạn phải có bộ đệm truy vấn và bạn có rất nhiều RAM, bạn có thể thực hiện các thao tác sau:
SET GLOBAL query_cache_size = 0;
SELECT SLEEP(60);
SET GLOBAL query_cache_size = 1024 * 1024 * 1024;
để xóa bộ nhớ cache truy vấn. Bạn mất tất cả các kết quả được lưu trong bộ nhớ cache, vì vậy hãy chạy các dòng này trong giờ thấp điểm.
Tôi cũng sẽ chỉ định như sau:
- truy vấn_cache_size = 1G
- truy vấn_cache_limit = 8M
Điều đó để lại 23G RAM. Tôi sẽ nâng cao như sau:
- innodb_buffer_pool_size = 12G
- key_buffer_size = 4G
Rời đi 7G. Điều này là đủ cho các kết nối hệ điều hành và DB.
Hãy nhớ rằng bộ đệm chính chỉ lưu trữ các trang chỉ mục MyISAM, trong khi Bộ đệm InnoDB lưu trữ dữ liệu và chỉ mục.
Thêm một đề xuất nữa: nâng cấp lên MySQL 5.5 để bạn có thể định cấu hình InnoDB cho nhiều CPU và nhiều luồng để đọc / ghi I / O.
Xem các bài đăng trước đây của tôi về việc sử dụng MySQL 5.5 kết hợp với truy cập nhiều CPU cho InnoDB
CẬP NHẬT 2012-09-06 14:56 EDT
Phương pháp của tôi để xóa bộ đệm truy vấn khá cực đoan vì nó làm mất dữ liệu được lưu trong bộ nhớ cache và tạo thành một phân đoạn RAM hoàn toàn khác. Như bạn đã chỉ ra trong bình luận của bạn, FLUSH QUERY CACHE
(như bạn đề xuất) hoặc thậm chí RESET QUERY CACHE
sẽ tốt hơn. Để làm rõ, khi tôi nói "không có cơ chế nội bộ", tôi có nghĩa là chính xác điều đó. Chống phân mảnh là cần thiết và phải được thực hiện thủ công. Nó sẽ cần phải được crontab'd .
Nếu bạn thực hiện DML (CHERTN, CẬP NHẬT, XÓA) trên InnoDB thường xuyên hơn trên MyISAM, tôi sẽ nói xóa hoàn toàn bộ đệm truy vấn, như tôi đã nói lúc đầu.