2010-08-24 13 views
6

Bir sitede yaklaşık 70K kayıt bulunan bir tablo görüntülenir ve sayfa başına 50 kayıt gösterilir. Sayfalandırma, sorguda limit offset,50 ile yapılır ve kayıtlar farklı sütunlarda sıralanabilir.Seç en son kayıtları seçerken çok daha yavaştır

(yaklaşık 60.000 bu yüzden ofset) çok daha yavaş sorguları yapar son sayfalarını tarama birinci sayfa (yaklaşık 10x)

bu limit komutunu kullanarak bir konu var mı gezinirken daha? Aynı sonuçları elde etmenin başka yolları var mı?

+0

İyi soru:

SELECT * FROM ( SELECT id FROM mytable ORDER BY value, id LIMIT $offset, $limit ) q JOIN mytable m ON m.id = q.id 

bu daha ayrıntılı açıklamalar için makalesine bakın: sütunlar dizine, böyle Sorgunuzla yeniden yazmak denemeye değer olabilir MySQL'in bu konuda nasıl çalıştığını bilmiyorum. – RedFilter

+0

Cevaplar için teşekkürler, daha sonra biraz hız kazanma umuduyla test edecek. – Omiod

cevap

7

Büyük ofsetlerle MySQL daha fazla rekor göz atmak zorunda. Sadece $offset + $limit üst kayıtlar sıralanır böylece planı (tüm kayıtlar göz gerektiği anlamına gelir) filesort kullansa bile

, MySQL çok daha etkili $offset alt değerleri için yapar bunu optimize eder.

SELECT * 
FROM mytable 
ORDER BY 
     value, id 
LIMIT 0, 10 

çıkış verdiğinde:

value id 

1  234 
3  57 
4  186 
5  457 
6  367 
8  681 
10  366 
13  26 
15  765 
17  345 -- this is the last one 

tipik bir çözüm, bu gibi sütunların son değerini kaydetmek ve sonraki sorgularda bunu yeniden dizinini oluşturmak için üzerinde sipariş sütunlar

sonraki sayfaya gitmek için, istersek: in kullandığı

SELECT * 
FROM mytable 
WHERE (value, id) > (17, 345) 
ORDER BY 
     value, id 
LIMIT 0, 10 

, (value, id) numaralı telefondan.

Elbette bu, isteğe bağlı erişim sayfalarında yardımcı olmaz, ancak sıralı göz atmada yardımcı olur.

Ayrıca, MySQL, geç satır aramasıyla ilgili belirli sorunlara yol açar. Ben,

+0

MySQL bu tuple tarzı sözdizimini destekler ('(val1, val2)> (1, 2)')? Bunu daha önce hiç görmedim. Birleştirici nedir (AND, varsayalım)? Her gün yeni bir şeyler öğreniyorsunuz sanırım ... – ircmaxell

+0

@ircmaxell: evet öyle. Sözlük, 'val1> 1 OR (val1 = 1 AND val2> 2) ' – Quassnoi

+0

İyi yanıt ile aynıdır. İşte aynı satırda iyi bir bilgi olduğunu düşünüyorum bir sunum: http://www.slideshare.net/Eweaver/efficient-pagination-using-mysql – nathan

2

MySQL limitleri nasıl ele alır. Bir dizine göre sıralama yapabiliyorsa (ve sorgu yeterince basitse), ilk offset + limit satırını bulduktan sonra arama işlemini durdurabilir. Yani LIMIT 0,10, sorgu yeterince basitse, yalnızca 10 satır taraması gerekebileceği anlamına gelir. Ancak LIMIT 1000,10, 'un en az numaralı telefonun 1010 satırı taraması gerektiği anlamına gelir. Elbette, taranması gereken gerçek satır sayısı, başka faktörlere bağlıdır. Ama buradaki nokta, limit + offset'un aşağı, taranması gereken satır sayısı alt sınırının o kadar düşük olmasıdır ...

Geçici çözümlere gelince, sorgularınızı kendiliğinden optimize ederdim. LIMIT yan tümcesi mümkün olduğunca verimli. EXPLAIN bu durumda arkadaş ...

İlgili konular