MySQL bir sorguda ORDER BY ve LIMIT'i nasıl işler?


251

Ben böyle bir sorgu var:

SELECT article FROM table1 ORDER BY publish_date LIMIT 20

ORDER BY nasıl çalışır? Tüm kayıtları sipariş edecek, sonra ilk 20'yi alacak mı yoksa 20 kayıt alacak publish_datemı ve bunları tarlaya göre sıralayacak mı?

Eğer sonuncuysa, en son 20 makaleyi almanız garanti edilmez.


6
Bazı publish_dates eşit olursa , onlar tarafından sipariş vermek belirli sonuçlar vermez, yani LIMITsayfalandırma için kullanırsanız , aynı öğeleri farklı sayfalarda elde edebileceğinizi unutmayın!
Konrad Morawski

Yanıtlar:


245

Önce sipariş verir, sonra ilk 20'yi alır. Bir veritabanı daha WHEREönce yan tümcedeki her şeyi işleyecektir ORDER BY.


1
Zamanlama aynı mı?
Yasar Arafath

7
Yanlış! LIMITtatili ORDER BY. İle LIMITbir ORDER BYdöner yanlış sonucu. LIMITbir şekilde döndürülen sonuç kümesini yeniden sıralarORDER BY
Green

6
@Yeşil, yanılıyorsun. Açıklama için bunu okuyun: dev.mysql.com/doc/refman/5.7/en/limit-optimization.html ORDER BY sütunu dizine eklendiğinde , kayıtları LIMIT olmadan farklı bir sırada döndürebilir. bu sütunda aynı değere sahip 1'den fazla kayıt.
yitwail

1
Bu tür problemler için hızlı bir çözüm, tercihen benzersiz değerlere sahip olacak şekilde bir sütun daha eklemektir, böylece veritabanı, ilk sıradaki sütunun değeri birden çok satır için aynı olduğunda sıraları sıralamak için tutarlı bir kural elde eder.
rineez

37

LIMIT deyimi, SELECT deyimi tarafından döndürülen satır sayısını sınırlamak için kullanılabilir. LIMIT, her ikisi de negatif olmayan tamsayı sabitleri (hazırlanmış ifadeler kullanıldığında hariç) olması gereken bir veya iki sayısal bağımsız değişken alır.

İki argümanla, ilk argüman döndürülecek ilk satırın ofsetini ve ikincisi döndürülecek maksimum satır sayısını belirtir. İlk satırın ofseti 0'dır (1 değil):

SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15

Belirli bir ofsetten sonuç kümesinin sonuna kadar tüm satırları almak için ikinci parametre için bir miktar büyük sayı kullanabilirsiniz. Bu ifade, 96. satırdan son satıra kadar olan tüm satırları alır:

SELECT * FROM tbl LIMIT 95,18446744073709551615;

Bir bağımsız değişkenle, değer sonuç kümesinin başından döndürülecek satır sayısını belirtir:

SELECT * FROM tbl LIMIT 5; # Retrieve first 5 rows

Başka bir deyişle, LIMIT row_count, LIMIT 0, row_count ile eşdeğerdir.

Tüm ayrıntılar: http://dev.mysql.com/doc/refman/5.0/en/select.html


5-14. Sıraları almıyor mu?
Adonis K.Kakoulidis

@adonis Hayır, değil. Örnek doğrudan MySQL Belgelerinden alınmıştır
dcaswell

5 sayısı 6. sıradır. 5 satır (0-4) yoksayılır.
Phil Perry

1
Ancak SİPARİŞ BY olmadan LIMIT kullanmak tutarsız sonuçlar verebilir! Ne yazık ki, LIMIT uygulanmadan veya DBMS sonucu keyfi olarak sipariş etmek ve daha sonra bu sette OFFSET ve LIMIT olmak için sonuç kümesinin tamamı sipariş edilmelidir. Ben bunun DBMS OFSET ve LIMIT dayalı rasgele sırayla dayalı alternatif bir Sorgu Planı seçerek nedeniyle olabileceğini okudum.
Barton

4
soru tarafından sınır ve sipariş soruyor. Ama cevap bu soru ile hiç ilgili değil
Shen liang

9

@James'in söylediği gibi, tüm kayıtları sipariş edecek ve ardından ilk 20 satırı alacaktır.

Bu nedenle, ilk yayınlanan 20 makaleyi almanız garanti edilir, daha yeni makaleler gösterilmez.

Durumunuza içinde, bunu eklemeniz önerilir desciçin order by publish_dateen yeni yazılar istiyorsanız, o zaman en yeni makale ilk olacak.

Sonucu artan sırada tutmanız gerekiyorsa ve yine de sadece en yeni 10 makaleyi istiyorsanız, mysql'den sonucunuzu iki kez sıralamasını isteyebilirsiniz.

Aşağıdaki bu sorgu sonucu azalan şekilde sıralayacak ve sonucu 10 ile sınırlayacaktır (parantez içindeki sorgu). Hala azalan düzende sıralanacaktır ve bundan memnun değiliz, bu yüzden mysql'den bir kez daha sıralamasını istiyoruz. Şimdi son satırda en yeni sonuca sahibiz.

select t.article 
from 
    (select article, publish_date 
     from table1
     order by publish_date desc limit 10) t 

order by t.publish_date asc;

Tüm sütunlara ihtiyacınız varsa, bu şekilde yapılır:

select t.* 
from 
    (select * 
     from table1  
     order by publish_date desc limit 10) t 

order by t.publish_date asc;

Veritabanını çeşitli şeyleri incelemek için el ile sorgu yazarken bu tekniği kullanıyorum. Bir üretim ortamında kullanmadım, ancak şimdi işaretlediğimde, ekstra sıralama performansı etkilemiyor.


2
Sadece 10 satır / öğe ile sınırlı olduğu için ekstra sıralamanızın performans üzerinde neredeyse ölçülebilir bir etkisi olmayabilir :-). Genel olarak, bir bellek içi tabloyu (bir alt seçimin ürettiği) sıralamak, milyonlarca satırınız yoksa veya DBMS, belleğe sığmadığı için sonuç kümesini diske sayfalamadığı sürece çok hızlı ve zar zor ölçülebilir DBMS'ye bağlı olarak sorguyu iptal edebilir).
Martin Kersten

7

Uygun bir indeks varsa, bu durumda publish_datesahada, o zaman MySQL'in istenen 20 kaydı almak için tüm indeksi taraması gerekmez - 20 kayıt indeksin başlangıcında bulunur. Ancak uygun bir dizin yoksa, tablonun tam olarak taranması gerekir.

Bu konuda 2009'dan kalma bir MySQL Performans Blogu makalesi var .


7

En eski veya en yeni kayıtları almak için siparişin sonuna [artan] veya [azalan] ekleyebilirsiniz

Örneğin, bu size ilk olarak en son kayıtları verecektir

ORDER BY stamp DESC

LIMITSonra maddeyi ekleyinORDER BY


3
Stackoverflow'a hoş geldiniz. Bence soruyu yanlış anlamış olabilirsiniz. "Nasıl sıralanacağını" değil, operasyonların sırasını soruyorlar. (Ama soru bir süre önce cevaplandığından beri tartışmalı;)
Leigh

5

SELECT article FROM table1 ORDER BY publish_date LIMIT 0,10 0'ın kaydın başlangıç ​​sınırı ve 10 kaydın olduğu bu kodu kullanabilirsiniz


8
Hayır, bu gerekli değil . LIMIT 10kısaltmasıdır LIMIT 0,10.
Lawrence Dol

2
Evet, LIMIT 0,10 için gerekli değil Ancak Bu Sınırı
Beğenebilirsiniz

3

LIMIT genellikle son işlem olarak uygulanır, bu nedenle sonuç önce sıralanır ve sonra 20 ile sınırlandırılır. Aslında, sıralama ilk 20 sıralanan sonuç bulunur bulunmaz duracaktır.


11
İkinci cümleniz ilk cümlenize aykırıdır. İlk 20 sonuç bulunduğunda sıralama durdurulamaz, çünkü belirttiğiniz gibi sonuçlar döndürülmeden önce sıralama yapılır. MySQL, sadece sıralama tamamlandıktan sonra ilk 20 sonucun ne olduğunu bilebilir.
Tom

@Tom, aslında, dizinlenmiş bir sütunla sipariş verirseniz olabilir. Burada açıklanmıştır: dev.mysql.com/doc/refman/5.7/en/limit-optimization.html
yitwail

-3

Ayrıca, LIMIT sözdizimi veritabanlarına göre farklıdır, örneğin:

mysql - SINIR 1, 2

postgres - SINIR 2 OFSET 1

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.