Sorgu önbelleği çok güzel bir özelliktir, ancak ona çok fazla dikkat etmeye cazip olmayın ve çok büyük yapmak için cazip olmayın. İç kısımlarından bazılarını anlamak muhtemelen bu konuda yardımcı olacaktır.
Sorgu önbelleği, kullanılabilir belleğin büyük bir bitişik parçası olarak başlar. Sonra "bloklar" bu büyük bloktan oyulmuştur:
- her önbellek sorgusu bir blok alır
- tamamlayıcı sonuç kümesi bir blok alır
- önbelleğe alınmış herhangi bir sorgu tarafından başvurulan her tablo (önbellekte bu tabloya başvuruda bulunan sorgu sayısı ne olursa olsun) her tablo için bir blok alır.
Blok boyutu dinamiktir, ancak sunucu query_cache_min_res_unit
blok başına minimum bayt ayırır ve tipik varsayılan 4096 bayttır.
Herhangi bir zaman sorgusu, eşlik eden sonuçları ve tablo referansları, ya altta yatan tablolar değiştirilerek geçersiz kılınarak ya da daha yeni sorgular için yer açmak için budama yaparak önbellekten kaldırılır, bu, bu blokların büyüklüğüne rağmen yeni delikler bırakır ve "serbest blok" sayısı genellikle artar ... ancak iki veya daha fazla bitişik blok serbest bırakılırsa, "serbest blok" sayısı sadece 1 artar ve "serbest bloklar", serbest bloklar zaten serbest bir blokla bitişiktir - bu serbest bloğun boyutu daha da büyür. Sorgu önbelleğindeki herhangi bir açık boş bellek bloğu 1 boş blok olarak sayılır.
Tabii ki, query_cache_min_res_unit
hiç kullanılmayacak olandan daha küçük bir serbest blok .
Yani, sorgu önbellek parçaları. Sunucu yeni bir sorgu önbelleğe almak istiyorsa ve yeterli büyüklükte boş bloklar düzenlenemiyorsa (bu açıklama aldatıcı basittir, çünkü temel algoritma karmaşıktır), başka bir şey budanmalıdır ... bu sizin Qcache_lowmem_prunes
. Budamaların ne olduğuna karar veren "en son kullanılan" (LRU) algoritması vardır.
Sunucunun neden belleği birleştirmediğini sormak mantıklı olurdu ... ama bu mantıklı değil. Sorgu önbelleği mümkün olduğunda yardımcı olur, ancak hiç stratejik değildir. Gereksiz bakım görevleriyle işlem süresine (özellikle küresel bir kilitte geçirilen zaman) yatırım yapmak istemezsiniz.
Önbelleğe alınan sonuçlar sürekli olarak değiştiğinden ve önbelleğin tüm amacı performansı artırmak olduğundan, sunucunun sorgu önbelleğindeki belleği yeniden düzenlemek - birleştirmek - zaman harcamak tersine verimli olacaktır.
Küresel kilit, aşırı büyük bir sorgu önbelleği kullanmak istememenizin çok iyi bir nedenidir ... sorgular önbelleğe alınmış olup olmadıklarını görmek için sıralarını beklerken sunucu orada çok fazla zaman harcayacak ve performansınız düşecektir .
Ancak bu qcache_free_blocks
aslında boş alan parçalanmasının bir göstergesidir. Bu, sorgu önbelleğinde artık bir çok bitişik olmayan kullanılabilir bellek bloğu var. Önbelleğe yeni bir sorgu eklenebilmesi için, sorguyu, sonuçlarını ve (bazen) tablo referanslarını içerecek kadar büyük bir boş alan yığını olmalıdır. Eğer yoksa, o zaman başka bir şey gitmek zorunda ... gördüğünüz şey bu. Yine, kullanılabilir alanın her zaman (kaynak kodunu okuyarak söyleyebileceğimden) bitişik olması gerekmediğini, ancak parçalanma olduğunda her delik doldurulmayacağını unutmayın.
Ancak, parçalanma, belirli bir iş yükü için zaman içinde dengelenme eğilimindedir, çünkü hiçbir şey genellikle beklediğiniz gibi sorgu önbelleğinde kalmaz.
Bunun nedeni, bazı açılardan, sorgu önbelleğinin basitliği bakımından mükemmel olmasıdır.
Önbelleğe alınmış bir sorgu tarafından başvurulan bir tablodaki veriler değiştiğinde, değişiklik önbelleğe alınan sonuçları etkilemese bile, bu tabloyu içeren tüm sorgular önbellekten kaldırılır. Bu, bir tablo değiştiğinde, ancak geri alınan bir InnoDB işleminde olduğu gibi değişmediğinde bile geçerlidir. Bu tabloya başvuran sorgu önbellek girdileri zaten temizlendi.
Ayrıca, sorgu önbelleği, sunucu sorguyu gerçekten ayrıştırmadan önce gelen her sorgu için denetlenir . Eşleşecek tek şey, tam olarak aynı olan başka bir sorgu, byte-for-byte. SELECT * FROM my_table
ve select * from my_table
bayt için bayt özdeş değildir, bu nedenle sorgu önbelleği aynı sorgu olduklarını fark etmez.
FLUSH QUERY CACHE
sorgu önbelleğini boşaltmaz. Sorgu önbelleğini birleştirir, bu yüzden Qcache_free_blocks
"1" olur. Tüm boş alan birleştirildi.
RESET QUERY CACHE
aslında sorgu önbelleğini temizler (tüm içeriğini temizler).
FLUSH STATUS
sayaçları temizler, ancak bu rutin olarak yapmak istediğiniz bir şey değildir, çünkü bu durum durum değişkenlerinin çoğunu sıfırlar SHOW STATUS
.
İşte bazı hızlı gösteriler.
Temel:
mysql> show status like '%qcache%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 67091120 |
| Qcache_hits | 0 |
| Qcache_inserts | 0 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 1 |
| Qcache_queries_in_cache | 0 |
| Qcache_total_blocks | 1 |
+-------------------------+----------+
Bir sorgu çalıştır ...
mysql> select * from junk where id = 2;
Toplam blok 3 arttı, 1 ekledi ve önbellekteki sorgular 1 oldu.
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 67089584 |
| Qcache_inserts | 1 |
| Qcache_queries_in_cache | 1 |
| Qcache_total_blocks | 4 |
+-------------------------+----------+
Aynı sorguyu çalıştır, ancak farklı büyük harf kullanımı ile ...
mysql> SELECT * FROM junk where id = 2;
Bu sorgu ayrı olarak önbelleğe alındı. Toplam bloklar sadece 2 arttı çünkü zaten tablo için bir blok tahsis ettik.
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 67088560 |
| Qcache_inserts | 2 |
| Qcache_queries_in_cache | 2 |
| Qcache_total_blocks | 6 |
+-------------------------+----------+
Şimdi, tablodaki farklı bir satırı değiştiriyoruz .
mysql> update junk set things = 'items' where id = 1;
Hem sorgular hem de tablo başvurusu önbellekten geçersiz kılınır ve bize 1 bitişik boş blok bırakır, tüm önbellek boşaltılır ve tüm boş alan tek bir blokta birleştirilir.
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 67091120 |
| Qcache_queries_in_cache | 0 |
| Qcache_total_blocks | 1 |
+-------------------------+----------+
MySQL, önbelleğe belirleyici olmayan SELECT NOW();
bir sorguyu (özellikle önbelleğe almamasını söylediğiniz herhangi bir sorgu gibi) depolamaz . SELECT SQL_NO_CACHE ...
sunucuya sonuçları önbellekte saklamamasını söyleyen direktiftir. Önbellek sonraki yürütmelerde aldatıcı hızlı bir yanıt verdiğinde, bir sorgunun gerçek yürütme süresini karşılaştırmak için kullanışlıdır.