私は現在、主に多くのテーブルで実行されているINSERT、DELETE、およびUPDATEステートメントの数が多いために、クエリキャッシュから多数の無効化が発生しているMySQLデータベースに取り組んでいます。
私が決定しようとしているのは、これらのテーブルに対して実行されているSELECTステートメントにクエリキャッシュを使用できるようにすることで、何らかのメリットがあるかどうかです。それらはすぐに無効化されるため、これらのテーブルを使用したSELECTステートメントでSQL_NO_CACHEを使用するのが最善の方法だと私には思われます。
頻繁な無効化のオーバーヘッドはそれだけの価値がありますか?
編集:以下のユーザー@RolandoMySQLDBAのリクエストに応じて、MyISAMとINNODBに関する情報を以下に示します。
InnoDB
MyISAM
追加情報:
あなただけでクエリキャッシュを無効にする必要があります
[mysqld]
query_cache_size = 0
mysqlを再起動します。なぜ私はそれを提案するのでしょうか???
クエリキャッシュは常にInnoDBに対応します。変更が他のトランザクションの繰り返し可能な読み取りに影響を与えない場合は、InnoDBのMVCCがクエリをクエリキャッシュから提供できるようになっていると便利です。残念ながら、InnoDBはそれを行いません。どうやら、かなり迅速に無効化され、おそらく再利用されていないクエリがたくさんあります。
MySQL 4.0のInnoDBの場合、クエリキャッシュはトランザクションに対して無効化されていました。 MySQL 4.1+の場合、テーブルごとにクエリキャッシュへのアクセスを許可すると、InnoDBはトラフィック警官を再生します。
あなたの質問の観点から、クエリキャッシュを削除することの正当化はそれほどオーバーヘッドではなく、InnoDBがそれを管理する方法であると私は言うでしょう。
InnoDBがクエリキャッシュと相互作用する方法の詳細については、本の213-215ページを参照してください "High Performance MySQL(Second Edition)" 。
データのすべてまたは大部分がMyISAMである場合、SQL_NO_CACHEを使用するという当初の考えを使用できます。
InnoDBとMyISAMが混在している場合は、キャッシュミスの高さに基づいて、アプリケーションに適したバランスを見つける必要があります。実際、 同じ本の209〜210ページ キャッシュミスの理由を指摘します。
- クエリは、非決定的な構成(CURRENT_DATEなど)が含まれているため、または結果セットが大きすぎて格納できないため、キャッシュできません。どちらのタイプのキャッシュ不可能なクエリでも、Qcache_not_cachedステータス変数が増加します。
- サーバーはこれまでにクエリを確認したことがないため、結果をキャッシュする機会がありませんでした。
- クエリの結果は以前にキャッシュされていましたが、サーバーはそれを削除しました。これを保持するのに十分なメモリがなかった、誰かがサーバーに削除するように指示した、または無効にされたために発生する可能性があります
キャッシュ不能なクエリがほとんどない高キャッシュミスの根本的な原因は次のとおりです。
- クエリキャッシュはまだウォームではありません。つまり、サーバーはキャッシュを結果セットで満たす機会がありませんでした。
- サーバーは、これまでにないクエリを参照しています。クエリが繰り返されない場合、これはキャッシュがウォームアップされた後でも発生する可能性があります。
- キャッシュの無効化がたくさんあります。
最新の更新情報を見ると、 query_cache_limit
1048576(1M)に設定します。これにより、すべての結果セットが1Mに制限されます。これより大きなものを取得すると、キャッシュされません。あなたが持っている間 query_cache_size
104857600(100M)に設定すると、完全な世界で100のキャッシュされた結果セットのみが許可されます。何百ものクエリを実行すると、断片化がかなり早く発生します。また、最小サイズの結果セットとして4096(4K)があります。残念ながら、mysqlにはクエリキャッシュを最適化するための内部メカニズムがありません。
クエリキャッシュが必要で、RAMが非常に多い場合は、次のコマンドを実行できます。
SET GLOBAL query_cache_size = 0;
SELECT SLEEP(60);
SET GLOBAL query_cache_size = 1024 * 1024 * 1024;
クエリキャッシュを削除します。キャッシュされた結果はすべて失われるため、これらの行はオフピーク時に実行してください。
以下も割り当てます。
23GのRAMが残ります。私は以下を提起します:
7Gが残ります。これは、OSおよびDB接続に適しています。
キーバッファーはMyISAMインデックスページのみをキャッシュし、InnoDBバッファープールはデータとインデックスをキャッシュすることに注意してください。
もう1つの推奨事項:MySQL 5.5にアップグレードして、読み取り/書き込みI/Oのために複数のCPUと複数のスレッド用にInnoDBを構成できるようにします。
MySQL 5.5をInnoDBの複数のCPUへのアクセスと組み合わせて使用することに関する私の以前の投稿を参照してください。
Nov 24, 2011
: mysql 5.5が5.1より遅い理由(linux、mysqlslapを使用)Oct 05, 2011
: 一部の新しいMySQLバージョンではクエリが長時間実行されますSep 20, 2011
: マルチコアとMySQLパフォーマンスJun 19, 2011
: MySQLベイクオフを適切に実行するにはどうすればよいですか?クエリキャッシュをクリアする私の方法は、キャッシュされたデータをホースし、RAMの完全に異なるセグメントを形成するため、かなり極端です。コメントで指摘したように、FLUSH QUERY CACHE
(ご提案のとおり)またはRESET QUERY CACHE
方が良いだろう。明確にするために、「内部メカニズムがない」と私が言ったとき、私はまさにそれを意味しました。最適化は必要であり、手動で行う必要があります。 crontabで入力する必要があります 。
MyISAMよりもInnoDBでDML(INSERT、UPDATE、DELETE)を頻繁に実行する場合、冒頭で述べたように、クエリキャッシュを完全に削除します。
悪い:query_cache_size = 1G
どうして?フラッシュに時間がかかるため。つまり、書き込みが発生すると、1GB全体がスキャンされ、変更されたテーブルへの参照が検索されます。 QCが大きいほど、これは遅くなります。データがめったに変更されない限り、50M以下のサイズをお勧めします。
QCはMyISAMとInnoDBの両方のオーバーヘッドです。グローバルミューテックスを削除しましたが、すぐに削除します。このミューテックスは、MySQLが約8コア以上を効果的に使用できない理由の1つです。
SQL_NO_CACHEは後ミューテックスがロックされるまで通知されません!そのフラグの唯一の用途はベンチマークです。
多くの場合、他のキャッシュにRAMを与えることをお勧めします。
私はそれの完璧なケースを考えることができます、そして私たちは徹底的にテストしてそれを生産で実行しました...私はそれを "fast lane"と呼びますクラスタリング戦略:
MaxScaleなどのプロキシを使用して読み取り/書き込み分割を行う場合、またはアプリケーションに対応している場合、めったに無効化されないテーブルの読み取りの一部を、クエリキャッシュがオンになっているスレーブにのみ送信し、残りをそれを持つ他のスレーブに送信できます。オフ。
これを実行し、結果として負荷テスト(ベンチマークではなく実際の取引)中にクラスターへの毎分4Mの呼び出しを処理します。アプリはいくつかの点でmaster_pos_wait()で待機するため、レプリケーションスレッドによって抑制されます。非常に高いスループットでQcacheの無効化を待機するステータスで確認しましたが、これらのスループットレベルはクラスターよりも高いですQcacheなしで可能です。
これが機能するのは、それらのマシンの小さなクエリキャッシュに無効にする必要のあるものがほとんどないためです(これらのクエリは、頻繁に更新されないテーブルにのみ関連します)。これらの箱は私たちの「速い車線」です。アプリケーションが実行する残りのクエリについては、Qcacheをオンにせずにボックスに移動するため、Qcacheと競合する必要はありません。