LoginSignup
3
4

More than 5 years have passed since last update.

CodeIgniter3のlimit()が生成するSQL

Posted at

はじめに

CodeIgniter 3.06で確認しました。

CodeIgniterには、Active Record(クエリビルダ)という機能があります。

これはあらかじめ用意されているメソッドを利用することで、SQLを書かずにクエリを発行する機能です。

一番シンプルな形はこれですね。

$query = $this->db->get('mytable');

これを実行すると、mytableの全レコードを取得します。

その他

  • select()
  • select_max()
  • from()
  • join()
  • where()
  • like()
  • group_by()
  • distinct()
  • order_by()
  • insert()
  • update()
  • delete()

といった対応するSQLをイメージできるメソッドが用意されています。

そんな中

  • limit()

というメソッドがあります。

limit()の構文はこうです。

limit(取得レコード数, オフセット)

21~30のレコードを取得したい場合は、

$this->db->limit(10,20);

のように書きます。

これはどのようなSQLが生成されるのでしょうか。MySQLはわかるのですが、Oracleはどうなるのでしょうか。
想定する結果を返してくれるのでしょうか。今回の調査の目的はここです。

というわけで、MySql、PostgreSql、Oracleでこのlimit()を使った場合にどのようなSQLが生成されるのかを調べてみました。

sampleテーブルから20件目から10件(21~30件目)を取得するソースです。

実際のソースはこのようになっています。

$this->db->limit(10,20);
$query = $this->db->get('sample');
return $query->result();

では、実際に発行されるSQLを確認してみます。

MySqlの場合

SELECT * FROM `sample` LIMIT 20, 10

想定どおりですね。MySQLは行数の制限がラクでよいですね。

PostgreSqlの場合

SELECT * FROM "sample" LIMIT 10 OFFSET 20

Postgresあまり使ったことなかったのですが、LIMITが用意されているのですね。
こちらも納得な感じです。

Oracleの場合

SELECT * FROM
  (
    SELECT
      inner_query.*, rownum rnum
    FROM
        (SELECT * FROM "sample" ) inner_query
    WHERE
      rownum < 31
  )
WHERE rnum >= 21

やっぱりOracleはこうなるしかないですよね。limit句がないので。

というようにoracleの場合は自動的にインラインビューとrownumを使ったSQLが組み立てられるという結果になりました。

データ量が多くなると性能的に厳しそうですが、フレームワークでこの差分を吸収してくれるのは助かりますね。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4