Skip to content

Eylül 30, 2010

3

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 3 Yorum Yorum Yaz
  1. Eyl 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.

    Cevapla
    • serkan
      Nis 2 2012
    • Emrah TUNÇEL
      Ağu 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…

      Cevapla

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

(gerekli)
(gerekli)