Skip to content

September 30, 2010

6

mysql_num_rows Yerine SQL_CALC_FOUND_ROWS

MySQL num rows

Merhaba arkadaşlar,

Bu yazımızda PHP ile MySQL sorgularımızın performansını artırmaya çalışacağız.

Neden SQL_CALC_FOUND_ROWS?

Özellikle büyük veritabanları ve yoğun işlem gören yerlerde mysql_num_rows fonksiyonunu kullanmak MySQL server ‘a büyük yükler getirecek ve sayfanız gereğinden yavaş açılacaktır.

Nasıl Kullanılır?

  • Sorgumuzun SELECT ifadesini SELECT COUNT(*) ile değiştirip satırları saydırabiliriz.
    SELECT COUNT(*) AS rows
    FROM `uyeler`
    WHERE `ulke` = 'Türkiye'

    Dönen Kayıt:

    +--------+
    | rows   |
    +--------+
    | 897012 |
    +--------+

    Kısıtlamalar:

    • En dışdaki SELECT kısmında sadece COUNT(*) olması gerekiyor
    • Sorgunuzda DISTINCT kullanıyorsanız bunu COUNT(*) ‘a veya devamına aktarmanız gerekiyor
    • Sorgunuzda GROUP BY kullanıyorsanız bunu COUNT(*) ‘a aktarmanız gerekiyor aksi taktirde birden fazla satır dönecektir

    Avantajları: Sorgumuzun limit kısmınsa birşey olup olmaması farketmiyor

    Dezavantajları: Eğer veritabanına bağlanmak için DAL kullanıyorsanız ve bu DAL satır sayısını otomatik olarak bir metodu çağırarak yapıyorsa veya yazdığınız DAL tüm sorgu adımlarını (SELECT DISTINCT|GROUP_CONCAT.., FROM, GROUP BY, HAVING, ORDER BY, LIMIT vb) ayrı ayrı tanımıyor sadece string olarak tutuyorsa biraz daha fazla kod yazmanız gerekiyor demektir.

  • Sorgumuzun SELECT kısmının hemen arkasına SQL_CALC_FOUND_ROWS ekleyerek satırları saydırabiliriz.
    SELECT SQL_CALC_FOUND_ROWS *
    FROM `uyeler`
    WHERE `ulke` = 'Türkiye'
    LIMIT 0

    İkinci bir sorgu gönderiyoruz:

    SELECT FOUND_ROWS()

    Dönen sonuç:

    +--------+
    | rows   |
    +--------+
    | 897012 |
    +--------+

    Kısıtlamalar: Hiçbir kısıtlama yok

    Avantajları: Sorgumuzun limit kısmınsa birşey olup olmaması farketmiyor

    Dezavantajları: Kullanımında hiçbir kısıtlama yoktur, sadece  SQL_CALC_FOUND_ROWS  ‘un eklenmesi yeterlidir. PhpMyAdmin ‘e biraz zaman alan bir sorgu gönderirseniz processlist ‘ten bu yöntemi kullandığını görebilirsiniz. Tek dezavantajı ise yukarıdaki COUNT yöntemine göre biraz ağır olduğunun söylenmesi.

Sonuç Olarak

Her ne kadar biz PHP ile karşılaştırıp anlatsakta yukarıdaki her iki yöntemde MySQL ‘e ait bir özellik olup kullandığınız dille pek alakası yoktur. Yani ister PHP ister JAVA isterseniz MySQL ‘e bağlanabildiğiniz başka bir dil yada MySQL Command Line kullanın bu yöntemleri uygulayabilirsiniz.

Toplam 6 Yorum Yorum Yaz
  1. Sep 30 2010

    Unutulmamalı ki, SQL_CALC_FOUND_ROWS özelliği limit kullanmış olsanız dahi tüm seti çekerek toplam sayıyı bulmaya çalışacağından, kayıt sayısının yüksek olduğu tablolarda sorguların yavaş gelmesine sebep olacaktır.

    Projenizde sorguları derleyen ara bir katman kullanarak COUNT(*) sorgusunun dezavantajlarını büyük oranda azaltılabileceğinden daima SQL_CALC_FOUND_ROWS kaynaklı sorgu yavaşlıklarının önüne geçilebilir.

    Reply
    • serkan
      Apr 2 2012

      +1

      Reply
    • Emrah TUNÇEL
      Aug 23 2012

      Veritabanı motorunu INNODB olarak kullanırsanız SQL_CALC_FOUND_ROWS sürekli indexlendiği için verilerin çokluğuna bakmaksızın aynı hızda sonuç üretilir.

      INNODB bir çok sorguda kendi bünyesindeki index yapılarını kullanarak veri çokluğuna bakmaksızın hızlı cevaplar üretebilir…

      Reply
  2. Can
    Mar 14 2013

    Bende sql optimizasyonu arayışı içerisindeyim… Bu yazıyı okuyun derim… yanılgıları düzeltebilir.

    http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/

    Reply
  3. Erhan
    Mar 4 2016

    hocam benim sorum şu sekil diyelimki üyeler diye bir tablom var ve bu tabloda uye_sira, uye_adi,uye_soyadı,memleketi, yasadigiyer gibi alanlar var ben burdaki üyeler arasında rastgele %7(değiştirilebilir %10 yada daha farklı) ‘lik kısmının listesi almak istediğimde nasıl bir yol izlemeliyim

    Reply
  4. Merve
    Apr 7 2016

    SELECT COUNT(*) AS rows
    FROM `uyeler`
    WHERE `ulke` = ‘Türkiye’

    Şimdi ben bu sorguyu yazdım ama sonucu ekrana php de optimizeli şekilde nasıl nasıl yazdıra bilirim? fetch_assoc yada farklı bir şey mi kullan malıyım?

    Reply

Sizin fikriniz nedir? Lütfen aşağıdaki formu kullanarak yorum yapın.

(gerekli)
(gerekli)