2009-09-14 8 views
5

geliştirmek. total_entries için çok özel bir sorguya sahibiz ve bu da DB'mize büyük bir yük getiriyor. Bu nedenle, toplam_entrileri sayfalamadan tamamen kesmek istiyoruz. Diğer bir deyişle, kullanma will_paginate: total_entries Ben koleksiyonu oluşturmak için <strong>paginate_by_sql</strong> yöntemi paginated edilecek kullandığı <strong>will_paginate</strong> güncel bir uygulama var uzun sorgu

yerine tipik sayfalama ekranın 'Önceki 1 [2] 3 4 5 sonraki', biz olur sadece bir 'sonraki - önceki' gibi düğme sadece. Ama birkaç şey bilmemiz gerek.
  1. önceki bağlantıyı görüntülemek musunuz? Bu, yalnızca mevcut seçimde mevcut olanlardan önce mevcut olan kayıtlar
  2. Bir sonraki linki görüntülüyor mu? total_entries: koleksiyonunda son Siciliniz kaynağı yoksa sayım satırlar için bir sorgu otomatik olarak oluşturulur docs

    itibaren

görüntülenmekte olduğunu, bu görüntülenemiyor olmaz. Bu oluşturulan SQL ile size tecrübe problemleri, sen isteyebilirsiniz Eğer uygulamasında elle sayımı gerçekleştirmek.

Yani sonuçta ideal durum şudur.

  • o
  • mevcut tüm sayfa numaralarını görüntülemek için gerek gezinmek için sadece bir sonraki/önceki düğmeleri kullanarak değil, yarı sayfalama ile bir anda veritabanında
  • Ekran 50 kayıtları çok fazla yük sebep oluyor çünkü total_entries saymak kaldır
  • Sadece buna göre

kimse benzer bir sorun ile çalıştı Has yanındaki düğmeyi ve önceki düğmesini görüntülemek veya buna bir çözüm bulmak düşünce var?

cevap

13

will_paginate sayım SQL jeneratör şaşırtmak karışanlar birleştirmeler vardır, özellikle, giriş sayısını hesaplamak gerçekten korkunç bir iş yok birçok fırsat olabilir.

İhtiyacınız olan tek şey basit bir sonraki/sonraki yöntemse, yapmanız gereken tek şey N + 1 girişlerini veritabanından almaya çalışmaktır ve yalnızca son sayfada olduğunuzdan N veya daha azını alırsanız . Örneğin

:

per_page = 10 
page = 2 

@entries = Thing.with_some_scope.find(:all, :limit => per_page + 1, :offset => (page - 1) * per_page) 

@next_page = @entries.slice!(per_page, 1) 
@prev_page = page > 1 

Kolayca bunu gerektirir, ya da denetleyici uzantısını oluşturan çeşitli modellerde dahil olabilecek bazı modülünde bu kozalayabilirsiniz.

Bunun, varsayılan will_paginate yönteminden önemli ölçüde daha iyi çalıştığını buldum.

tek performans sorunu

sofralarınıza boyutuna bağlı bir sorun olabilir MySQL bir sınırlamadır.Sebebi ne olursa olsun

, bu MySQL küçük LIMIT ile bir sorgu gerçekleştirmek için gereken süre OFFSET doğru orantılıdır. Aslında, veritabanı motoru, belirli bir ofset değerine kadar giden tüm satırları okur, ardından beklediğiniz gibi ilerlememek için bir sonraki LIMIT sayı satırını döndürür. Eğer, performansı bulabilir 100.000 artı aralıktaki değerleri OFFSET sahip olduğunuz büyük veri setleri için

, önemli ölçüde düşürür. Bunun nasıl ortaya çıkacağı, yükleme sayfa 1'in çok hızlı olduğu, sayfa 1000'in biraz yavaş olduğu, ancak sayfa 2000'in aşırı yavaş olduğudır.

+0

Fikir için teşekkürler. Ben hack alıp neye gelebileceğimi göreceğim. Başa çıkmak için uzun süren özel SQL sorgularım var ama bence bunları çözüme kavuşturmalı ve performansın nasıl olacağına dair bir fikre sahip olmalıyım. Teşekkürler! – mwilliams

+0

Cevabınız için teşekkürler. Güzel ve basit ve böyle basit bir çözümün ötesine baktım. Uygulamamın çoğu yerinde ve zaten çok daha iyi görünüyor. Bir sonraki/önceki düğmelerle ilgili sorunlarım olsa da, yakında yeteri kadar dövüleceğim. Tekrar teşekkürler! – mwilliams