2011-07-12 6 views
27

bu sql ilk çalıştırdığınızda çalışmaz: Ben çeşitli yöntemler denedik SQL_NO_CACHE tekrar çalıştırın ve SQL_NO_CACHE arttıkça, etkili olması için görünmüyor, 39 saniye gerekmektedir,

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

ve hatta mysql server veya değiştirmek tablosu adını yeniden, ama yine de 39 saniye başka SQL ve SQL_NO_CACHE üzerinde ilk çalıştırmada bir artış yerini

bu SQL çalıştırmak izin veremem, sorun aynıdır:

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) 

Sebep nedir? Aynı SQL çalışma zamanını nasıl alabilirim? RESET QUERY CACHEFLUSH QUERY CACHEFLUSH TABLESSET SESSION query_cache_type=off MySQL devlet önbellek kapatıldı

çalışmıyor:

Ben 39 saniye

BTW

gerçekleştirmek için bu SQL optimize etmek için bir yol bulmak istiyorum

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) 

bu SQL'i açıklar, kullanılmış site + bitiş zamanı bileşik dizini (site_endtime olarak adlandırılır):

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

Bu sorgu için ** kompozit ** dizini kullanıyor musunuz? – Karolis

+0

@Karolis bir site + bitiş saati (site_endtime' adı verilen) bileşik dizini var – Koerr

+1

Belirli bir veritabanı hakkında hiçbir şey bilmiyorum, ama başka bir bileşik endeksi (site + alan + bitiş) oluşturmak iyi bir fikir olurdu gibi görünüyor . MySql daha az satır okuyacaktır, bu yüzden daha hızlı hale gelmelidir. – Karolis

cevap

13

cevap için "Aynı SQL çalışma zamanını nasıl alabilirim?" - yapamazsınız. Sorunuzda bazı satırlar okunuyorsa, önbelleğe alınmışlar, kullanılan depolama motoruna bağlı olarak, bu satırlar OS önbelleğinde (myisam) veya arabellek havuzunda (innodb). Satırlar önbelleğe alınmışsa, aynı sorguyu ikinci kez çalıştırmak çok daha hızlıdır, çünkü MySQL disketten okumak zorunda değildir.

+1

Bu 39 saniye sql çalıştırmak için optimize etmek için hiçbir yolu yok? – Koerr

+0

@Zenofo, "soğuk önbellek" çalışmasını çoğaltmaya çalışmanın tek yolu mysql'i yeniden başlatmaktır. – nathan

+1

İndeks/veri dosyaları OS dosyası/blok önbelleğinde ise, mysql'yi yeniden başlatma bile kesemeyebilir. – nos

0
  1. bkz: http://forums.mysql.com/read.php?24,225286,225468#msg-225468
  2. Eğer RESET QUERY CACHE (eğer RELOAD ayrıcalığı gerekir) deneyebilirsiniz sadece bu yukarıdaki bağlantıyı okumak zorunda muhtemelen çalışmaz halde ya :(
+2

Denedim, 'SIFIR SORGU SEVİYE 've' YIKAMA TABLOLARI ', SET SESSION query_cache_type = kapalı;' çalışmıyor – Koerr

7

Geçerli çalışma zamanında hesaplanan herhangi bir SQL işlevinin önbelleğe alınmayacağı izleniminin altındaydım. Aşağıdaki gibi bir şey yapmayı denediniz mi?

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

Bu bana çok yardımcı oldu. Teşekkürler. –

36

İlk sorgu önbelleğine sonucu koymak değil MySQL anlatmak için SQL_NO_CACHE kullanmalıdır. İkinci sorgu önbelleği kullanır ve MySQL'e bu sorgunun sonucunu önbelleğe almamasını söyler, bu hiçbir şey yapmaz.

tl; dr - Sorgularınızı tersine çevirin.

+7

Bunun neden doğru cevap olarak seçilmediğini anlamıyorum. Olmalı. – brooNo

+5

[MySQL docs] 'a göre (http://dev.mysql.com/doc/refman/5.6/en/query-cache-in-select.html) ikinci SELECT'teki SQL_NO_CACHE, sorgu önbelleğini kontrol etmeyi atlamalıdır. Yukarıdakiler gerekli olmamalıdır: "Sunucu sorgu önbelleğini kullanmaz. Sonucun önbelleğe alınmış olup olmadığını görmek için sorgu önbelleğini denetler ve sorgu sonucunu önbelleğe almaz." – Nikita

+2

** Bu yanıt doğru değil ** çünkü 'SQL_NO_CACHE' ile bir sorgu da hiçbir zaman sorgu önbelleğinden gelen bir yanıtla sunulabilir. Sorgu önbelleği, * ayrıştırılmadan önce sorgunun * kesin baytını * kullanarak * SQL çözümleyicinin çalıştırılmasından * önce denetlenir. Tam olarak aynı bayttan oluşan bir sorgunun yanıtı önbellekte zaten bulunmadıkça, kullanılabilecek bir sonuç yoktur ... ve "SQL_NO_CACHE" ile bir sorgudan sonuç asla sorgu önbelleğine yazılmayacağından asla önbellekten sunulmaz. 'SQL_NO_CACHE', OP'nin beklediği gibi davranmayacak şekilde garanti edilir, asla önbellekten bir yanıt vermez. –