2011-07-12 42 views
27

Lần đầu tiên tôi chạy sql này, cần 39 giây, khi tôi chạy lại và tăng SQL_NO_CACHE, dường như không có hiệu lực:SQL_NO_CACHE không hoạt động

mysql> select count(*) from `deal_expired` where `site`=8&&`area`=122 && 
endtime<1310444996056; 
+----------+ 
| count(*) | 
+----------+ 
|  497 | 
+----------+ 
1 row in set (39.55 sec) 

mysql> select SQL_NO_CACHE count(*) from `deal_expired` where `site`=8&&`area`= 
122 && endtime<1310444996056; 
+----------+ 
| count(*) | 
+----------+ 
|  497 | 
+----------+ 
1 row in set (0.16 sec) 

Tôi đã thử một loạt các phương pháp, here

và thậm chí khởi động lại máy chủ mysql hoặc thay đổi tên bảng, nhưng tôi vẫn không thể để 39 giây chạy SQL này

tôi thay thế khác SQL, và sự gia tăng trong thời gian đầu tiên trên SQL_NO_CACHE, vấn đề là như nhau:

mysql> select SQL_NO_CACHE count(*) from `deal_expired` where `site`=25&&`area`= 
134 && endtime<1310483196227; 
+----------+ 
| count(*) | 
+----------+ 
|  315 | 
+----------+ 
1 row in set (2.17 sec) 

mysql> select SQL_NO_CACHE count(*) from `deal_expired` where `site`=25&&`area`= 
134 && endtime<1310483196227; 
+----------+ 
| count(*) | 
+----------+ 
|  315 | 
+----------+ 
1 row in set (0.01 sec) 

Lý do là gì? Làm cách nào để có được cùng một thời gian chạy SQL?

Tôi muốn tìm một cách để tối ưu hóa SQL này để thực hiện 39 giây

BTW: RESET QUERY CACHEFLUSH QUERY CACHEFLUSH TABLESSET SESSION query_cache_type=off không hoạt động

bộ nhớ cache bang mysql đã bị đóng cửa:

mysql> SHOW STATUS LIKE "Qcache%"; 
+-------------------------+-------+ 
| Variable_name   | Value | 
+-------------------------+-------+ 
| Qcache_free_blocks  | 0  | 
| Qcache_free_memory  | 0  | 
| Qcache_hits    | 0  | 
| Qcache_inserts   | 0  | 
| Qcache_lowmem_prunes | 0  | 
| Qcache_not_cached  | 0  | 
| Qcache_queries_in_cache | 0  | 
| Qcache_total_blocks  | 0  | 
+-------------------------+-------+ 
8 rows in set (0.04 sec) 

mysql> select count(*) from `deal_expired` where `site`=25&&`area`=134 && endtime<1310 
483196227; 
+----------+ 
| count(*) | 
+----------+ 
|  315 | 
+----------+ 
1 row in set (0.01 sec) 

mysql> SHOW STATUS LIKE "Qcache%"; 
+-------------------------+-------+ 
| Variable_name   | Value | 
+-------------------------+-------+ 
| Qcache_free_blocks  | 0  | 
| Qcache_free_memory  | 0  | 
| Qcache_hits    | 0  | 
| Qcache_inserts   | 0  | 
| Qcache_lowmem_prunes | 0  | 
| Qcache_not_cached  | 0  | 
| Qcache_queries_in_cache | 0  | 
| Qcache_total_blocks  | 0  | 
+-------------------------+-------+ 
8 rows in set (0.00 sec) 

giải thích SQL này, trang web được sử dụng + chỉ mục tổng hợp thời gian kết thúc (có tên site_endtime):

mysql> explain select count(*) from `deal_expired` where `site`=8&&`area`=122 && endti 
me<1310444996056; 
+--------+------+-------------------------------+--------------+---------+------ 
-+------+-------------+ 
| table | type | possible_keys     | key   | key_len | ref 
| rows | Extra  | 
+--------+------+-------------------------------+--------------+---------+------ 
-+------+-------------+ 
| deal_expired | ref | name,url,endtime,site_endtime | site_endtime |  4 | const 
| 353 | Using where | 
+--------+------+-------------------------------+--------------+---------+------ 
-+------+-------------+ 
1 row in set (0.00 sec) 
+0

Bạn có sử dụng chỉ mục ** tổng hợp ** cho truy vấn này không? – Karolis

+0

@Karolis có một trang web + endtime (tên là 'site_endtime') chỉ số tổng hợp – Koerr

+1

Tôi không biết gì về cơ sở dữ liệu cụ thể của bạn, nhưng có vẻ như bạn nên tạo một chỉ mục tổng hợp khác (site + area + endtime) . MySql sẽ đọc ít hàng hơn, vì vậy nó sẽ trở nên nhanh hơn. – Karolis

Trả lời

13

Câu trả lời cho "Làm thế nào tôi có thể nhận được cùng một thời gian chạy SQL?" Là - bạn không thể. Nếu truy vấn của bạn đọc một số hàng, chúng được lưu trong bộ nhớ cache, phụ thuộc vào công cụ lưu trữ đang sử dụng, các hàng đó nằm trong bộ đệm hệ điều hành (myisam) hoặc trong vùng đệm (innodb). Nếu các hàng được lưu trữ, chạy cùng một truy vấn lần thứ hai nhanh hơn nhiều, bởi vì MySQL không phải đọc từ đĩa.

+1

Rằng tôi không có cách nào để tối ưu hóa điều này để chạy 39 giây sql? – Koerr

+0

@Zenofo, cách duy nhất để cố gắng tạo lại "bộ nhớ cache lạnh" chạy là khởi động lại mysql. – nathan

+1

Ngay cả khi khởi động lại mysql cũng có thể không cắt nó, nếu các tệp chỉ mục/dữ liệu nằm trong tệp bộ nhớ cache/tệp hệ điều hành. – nos

0
  1. see: http://forums.mysql.com/read.php?24,225286,225468#msg-225468
  2. bạn có thể thử RESET QUERY CACHE (bạn cần đặc quyền RELOAD) mặc dù có chỉ cần đọc các diễn đàn này có thể sẽ không làm việc, hoặc :(
+2

Tôi đã thử, 'RESET QUERY CACHE' và' FLUSH TABLES', 'SET SESSION query_cache_type = off;' không hoạt động – Koerr

7

Tôi đã có ấn tượng rằng bao gồm bất kỳ loại hàm SQL nào được tính toán trong thời gian chạy hiện tại sẽ không lưu vào bộ nhớ cache. Bạn đã thử làm một cái gì đó như sau?

select count(*), now() from `deal_expired` where `site`=8&&`area`=122 && endtime<1310444996056; 
+0

Điều này đã giúp tôi rất nhiều. Cảm ơn. –

36

Truy vấn đầu tiên nên sử dụng SQL_NO_CACHE nói với MySQL không để đưa kết quả vào bộ nhớ cache. Truy vấn thứ hai sử dụng bộ nhớ cache và yêu cầu MySQL không lưu vào bộ nhớ cache kết quả của truy vấn đó, mà không làm gì cả.

tl; dr - Đảo ngược truy vấn của bạn.

+7

Tôi không hiểu tại sao điều này không được chọn làm câu trả lời đúng. Nó nên được. – brooNo

+5

Theo [MySQL tài liệu] (http://dev.mysql.com/doc/refman/5.6/en/query-cache-in-select.html) 'SQL_NO_CACHE' trên SELECT thứ hai nên bỏ qua kiểm tra bộ nhớ cache truy vấn, do đó, ở trên không cần thiết: "Máy chủ không sử dụng bộ đệm truy vấn. Máy chủ không kiểm tra bộ nhớ cache truy vấn để xem liệu kết quả đã được lưu trong bộ nhớ cache hay không cũng sẽ lưu kết quả truy vấn." – Nikita

+2

** Câu trả lời này không chính xác **, vì truy vấn có 'SQL_NO_CACHE' cũng không bao giờ có thể được phục vụ với phản hồi từ bộ đệm truy vấn. Bộ nhớ cache truy vấn được chọn * trước khi * trình phân tích cú pháp SQL chạy, sử dụng * byte chính xác * của truy vấn để đối sánh. Trừ khi phản hồi cho truy vấn được tạo thành từ cùng một byte đã có trong bộ nhớ cache, không có kết quả nào có thể sử dụng ... và vì kết quả từ truy vấn có 'SQL_NO_CACHE' sẽ không bao giờ được ghi vào bộ đệm truy vấn, nó có thể không bao giờ được phục vụ từ bộ nhớ cache. Vì vậy, 'SQL_NO_CACHE' được bảo đảm hoạt động như OP mong đợi, không bao giờ phục vụ một phản hồi từ bộ nhớ cache. –