web-dev-qa-db-ja.com

MYSQL - ORDER BYとLIMIT

このようなクエリがあります。

SELECT article FROM table1 ORDER BY publish_date LIMIT 20

ORDER BYはどのように機能しますか?すべてのレコードを順序付けしてから最初の20レコードを取得しますか、それとも20レコードを取得してpublish_dateフィールドでそれらを順序付けしますか。

それが最後のものであるなら、あなたは本当に最新の20の記事を得ることが保証されていません。

214
Alex

データベースは最初に順序付けしてから、最初の20を取得します。データベースでは、WHERE句内のORDER BYの前にあるものもすべて処理されます。

220
James

LIMIT句を使用して、SELECT文によって返される行数を制限できます。 LIMITは1つまたは2つの数値引数を取りますが、両方とも負でない整数定数でなければなりません(準備済みステートメントを使用する場合を除く)。

2つの引数がある場合、最初の引数は返す最初の行のオフセットを指定し、2番目の引数は返す最大行数を指定します。最初の行のオフセットは0です(1ではありません)。

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

特定のオフセットから結果セットの最後までのすべての行を取得するには、2番目のパラメータに大きな数を使用できます。このステートメントは、96行目から最後までのすべての行を取得します。

SELECT * FROM tbl LIMIT 95,18446744073709551615;

引数が1つの場合、値は結果セットの先頭から返される行数を指定します。

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

つまり、LIMIT row_countはLIMIT 0、row_countと同じです。

上のすべての詳細: http://dev.mysql.com/doc/refman/5.0/en/select.html

36
bensiu

最古のレコードまたは最新のレコードを取得することで、注文の最後に[asc]または[desc]を追加できます。

例えば、これはあなたに最新の記録を最初に与えるでしょう

ORDER BY stamp DESC

ORDER BYの後にLIMIT句を追加します

7
Paul

この場合、publish_dateフィールドに適切なインデックスがある場合、MySQLは要求された20レコードを取得するためにインデックス全体をスキャンする必要はありません - 20レコードはインデックスの先頭にあります。しかし、適切なインデックスがない場合は、テーブルのフルスキャンが必要になります。

これについては、2009年から MySQL Performance Blogの記事 があります。

7
martin clayton

@Jamesが言うように、すべてのレコードを並べ替えてから、最初の20行を取得します。

それはそうであるので、あなたは20最初に公開された記事を得ることが保証されています、新しいものは表示されません。

あなたの状況では、私はあなたが最新の記事が欲しいならdescorder by publish_dateに追加することをお勧めします、そして最新の記事が最初になります。

結果を昇順にして、それでも10件の最新の記事のみを表示する必要がある場合は、mysqlに結果を2回ソートするよう依頼できます。

以下のこのクエリは結果を降順にソートし、結果を10に制限します(つまり、括弧内のクエリです)。それはまだ降順でソートされ、それに満足していないので、もう一度ソートするようにmysqlに依頼します。これで、最後の行に最新の結果が得られました。

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

order by t.publish_date asc;

すべての列が必要な場合は、次のようにします。

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

order by t.publish_date asc;

データベースを調べてさまざまなことを手動で行うときに、この手法を使用します。実稼働環境では使用していませんが、ベンチマーク時に余分なソートがパフォーマンスに影響を与えることはありません。

このコードSELECT article FROM table1 ORDER BY publish_date LIMIT 0,10を使用できます。0はレコードの開始制限、10はレコード数です。

4

通常、LIMITは最後の操作として適用されるため、結果は最初にソートされ、次に20に制限されます。実際、ソートされた最初の20の結果が見つかるとすぐにソートは停止します。

2
Egor Pavlikhin