2011-07-12 5 views
27

私はこのSQLを最初に実行したときに動作しません:私は、様々な方法を試してみました SQL_NO_CACHEは、私は再び実行し、SQL_NO_CACHEを増やす際に、有効にするようではありませんが、39秒を必要とし、

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) 

here

とさえMySQLサーバまたは変更テーブル名を再起動し、私はまだ、私は別のSQL、およびSQL_NO_CACHE上の最初の実行の増加を置き換え39秒は、このSQL

を実行させることができない、問題は同じです。

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) 

何故ですか? 同じSQL実行時間を取得するにはどうすればよいですか?

私は39秒ところで

を実行するには、このSQLを最適化する方法を見つけたい:

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) 

を: RESET QUERY CACHE FLUSH QUERY CACHE FLUSH TABLES SET SESSION query_cache_type=off

mysqlの状態キャッシュが閉じられた動作しません。

説明このSQLは、site + endtime複合インデックス(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

このクエリに** composite ** indexを使用していますか? – Karolis

+0

@Karolisはsite + endtime(site_endtime'という名前の)コンポジットインデックス – Koerr

+1

あなたの特定のデータベースについては何も知らないが、別のコンポジットインデックス(site + area + endtime)を作成することをお勧めします。 MySqlは少ない行を読み込むので、より高速になるはずです。 – Karolis

答えて

13

への答え「同じSQL実行時間をどうやって得ることができますか?」ということはできません。 クエリがいくつかの行を読み込むと、それらは使用中のストレージエンジンに依存してキャッシュされ、それらの行はOSキャッシュ(myisam)またはバッファプール(innodb)のいずれかにあります。行がキャッシュされている場合、同じクエリを2回実行するほうがはるかに高速です。なぜなら、MySQLはディスクから読み込む必要がないからです。

+1

を動作しません。 – Koerr

+0

@ Zenofo、 "cold cache"の実行を再現させる唯一の方法は、mysqlを再起動することです。 – nathan

+1

インデックス/データファイルがOSファイル/ブロックキャッシュ内にある場合、mysqlを再起動してもそれをカットしないことがあります。 – nos

0
  1. 参照:http://forums.mysql.com/read.php?24,225286,225468#msg-225468
  2. ちょうどこの上のリンクを読んで持つことは、おそらくどちらか動作しませんが、あなたは(あなたがRELOAD権限が必要です)RESET QUERY CACHEを試みることができる:(
+2

私は' QUERY cache'にと 'FLUSH TABLES'、' SET SESSIONのquery_cache_type =オフをリセット、試してみましたか? – Koerr

7

私は、現在のランタイムで計算されるあらゆる種類のSQL関数を含めてキャッシュしないという印象を受けました。あなたは次のようなことをやってみましたか?

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

これは私を助けました。ありがとう。 –

36

最初のクエリは、キャッシュに結果を入れないでMySQLを伝えるためにSQL_NO_CACHEを使用する必要があります。 2番目のクエリはキャッシュを使用し、そのクエリの結果をキャッシュしないようにMySQLに指示しますが、何もしません。

tl; dr - クエリを逆転させます。

+7

これが正解として選択されなかった理由は分かりません。そのはず。よると – brooNo

+5

[MySQLのドキュメント](http://dev.mysql.com/doc/refman/5.6/en/query-cache-in-select.html) '2番目のSELECTのSQL_NO_CACHE'は、クエリキャッシュをチェックしなければならないのでスキップサーバーはクエリキャッシュを使用せず、クエリキャッシュをチェックして結果が既にキャッシュされているかどうかを確認したり、クエリ結果をキャッシュしたりすることはありません。 – Nikita

+2

**この答えは正しくありません**。なぜなら、 'SQL_NO_CACHE'を伴うクエリは、クエリキャッシュからの応答では決して扱われないからです。クエリキャッシュは、SQLパーサーが実行される前に照合の* exactバイト*を使って照合されます。まったく同じバイトで構成されたクエリに対する応答がキャッシュ内にすでにある場合を除き、使用する一切の可能な結果がありません...そして、それができる、SQL_NO_CACHE' 'でクエリから結果がクエリキャッシュに書き込まれることはありませんので、キャッシュからは絶対に提供されません。したがって、「SQL_NO_CACHE」はOPが期待するように動作することが保証され、キャッシュからの応答は決して提供されません。 –

関連する問題