Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 27.1Mb
PDF (A4) - 27.1Mb
EPUB - 7.5Mb
HTML Download (TGZ) - 7.2Mb
HTML Download (Zip) - 7.2Mb


12.14 情報関数

表 12.18 情報関数

名前 説明
BENCHMARK() 式を繰り返し実行します
CHARSET() 引数の文字セットを返します
COERCIBILITY() 文字列引数の照合順序強制性値を返します
COLLATION() 文字列引数の照合順序を返します
CONNECTION_ID() 接続のための接続 ID (スレッド ID) を返します
CURRENT_USER(), CURRENT_USER 認証済みユーザー名とホスト名
DATABASE() デフォルト (現在) のデータベース名を返します
FOUND_ROWS() LIMIT 句付き SELECT で、LIMIT 句がない場合に戻される可能性がある行の数です
LAST_INSERT_ID() 前回の INSERT での AUTOINCREMENT カラムの値です
ROW_COUNT() 更新された行数
SCHEMA() DATABASE() のシノニムです
SESSION_USER() USER() のシノニムです
SYSTEM_USER() USER() のシノニムです
USER() ユーザー名と、クライアントによって提供されるホスト名です
VERSION() MySQL サーバーのバージョンを示す文字列を返します

  • BENCHMARK(count,expr)

    BENCHMARK() 関数は、式 exprcount の回数だけ繰り返し実行します。MySQL による式の処理速度を計測する際に使用される場合もあります。結果の値は常に 0 になります。この使用目的は、mysql クライアント内から、クエリーの実行時間をレポートすることです。

    mysql> SELECT BENCHMARK(1000000,ENCODE('hello','goodbye'));
    +----------------------------------------------+
    | BENCHMARK(1000000,ENCODE('hello','goodbye')) |
    +----------------------------------------------+
    |                                            0 |
    +----------------------------------------------+
    1 row in set (4.74 sec)
    

    レポートされる時間は、クライアント側での経過時間であり、サーバー側での CPU 時間ではありません。BENCHMARK() を複数回実行し、サーバーマシン上の負荷量について結果を解釈することをお勧めします。

    BENCHMARK() の目的は、スカラー式の実行時パフォーマンスを測定することです。これにより、その使用方法や結果の解釈方法について、重要ないくつかの推測が提供されます。

    • スカラー式しか使用できません。式をサブクエリーにすることはできますが、単一のカラムおよび最大でも単一の行が返される必要があります。たとえば、テーブル t に複数のカラムや複数の行が含まれていると、BENCHMARK(10, (SELECT * FROM t)) は失敗します。

    • SELECT expr ステートメントを N 回実行する場合と、SELECT BENCHMARK(N, expr) を実行する場合とでは、発生するオーバーヘッドの量が異なります。この 2 つは非常に異なる実行プロファイルを持つため、両者の所要時間は同一になりません。前者では、パーサー、オプティマイザ、テーブルロック、および実行時評価がそれぞれ N 回ずつ発生します。後者では、実行時評価のみが N 回発生し、その他のすべてのコンポーネントは 1 回だけ発生します。割り当て済みのメモリー構造体は再使用され、集約関数で評価済みの結果をローカルキャッシュに入れるなどの実行時最適化によって、結果が変わる可能性もあります。したがって、BENCHMARK() を使用して、実行時コンポーネントに高い重みを付加し、ネットワーク、パーサー、オプティマイザなどで導入されたノイズを削除することで、そのコンポーネントのパフォーマンスが測定されます。

  • CHARSET(str)

    文字列引数の文字セットを返します。

    mysql> SELECT CHARSET('abc');
            -> 'latin1'
    mysql> SELECT CHARSET(CONVERT('abc' USING utf8));
            -> 'utf8'
    mysql> SELECT CHARSET(USER());
            -> 'utf8'
    
  • COERCIBILITY(str)

    文字列引数の照合順序強制性値を返します。

    mysql> SELECT COERCIBILITY('abc' COLLATE latin1_swedish_ci);
            -> 0
    mysql> SELECT COERCIBILITY(USER());
            -> 3
    mysql> SELECT COERCIBILITY('abc');
            -> 4
    

    戻り値の意味は、次の表に示すとおりです。値が低いほど、優先順位は高くなります。

    型変換属性 意味
    0 明示的な照合順序 COLLATE 句の値
    1 照合順序なし さまざまな照合順序との文字列の連結
    2 暗黙的な照合順序 カラム値、ストアドルーチンパラメータ、またはローカル変数
    3 系統定数 USER() の戻り値
    4 型変換可能 リテラル文字列
    5 無視可能 NULL または NULL から派生した式
  • COLLATION(str)

    文字列引数の照合順序を返します。

    mysql> SELECT COLLATION('abc');
            -> 'latin1_swedish_ci'
    mysql> SELECT COLLATION(_utf8'abc');
            -> 'utf8_general_ci'
    
  • CONNECTION_ID()

    接続用の接続 ID (スレッド ID) を返します。すべての接続は、現在接続されているクライアントのセット間で一意の ID を持っています。

    CONNECTION_ID() で返される値の型は、INFORMATION_SCHEMA.PROCESSLIST テーブルの ID カラム、SHOW PROCESSLIST 出力の Id カラム、およびパフォーマンススキーマ threads テーブルの PROCESSLIST_ID カラムに表示される値と同じです。

    mysql> SELECT CONNECTION_ID();
            -> 23786
    
  • CURRENT_USER, CURRENT_USER()

    現在のクライアントを認証する際にサーバーで使用された MySQL アカウントを表すユーザー名とホスト名の組み合わせを返します。このアカウントで、アクセス権限が決まります。戻り値は、utf8 文字セット内の文字列です。

    CURRENT_USER() の値は、USER() の値とは異なる可能性があります。

    mysql> SELECT USER();
            -> 'davida@localhost'
    mysql> SELECT * FROM mysql.user;
    ERROR 1044: Access denied for user ''@'localhost' to
    database 'mysql'
    mysql> SELECT CURRENT_USER();
            -> '@localhost'
    

    この例は、クライアントが davida のユーザー名を指定 (USER() 関数の値で指定されます) したが、サーバーは匿名のユーザーアカウント (CURRENT_USER() 値の空のユーザー名部分に表示されます) を使用してクライアントを認証したことを示しています。これが発生する原因として、davida の付与テーブルにアカウントが一覧表示されていないことが考えられます。

    ストアドプログラムまたはビューでは、SQL SECURITY INVOKER 特性で定義されていなければ、CURRENT_USER() はオブジェクトを定義したユーザー (その DEFINER 値で指定されます) のアカウントを返します。後者の場合、CURRENT_USER() はオブジェクトを呼び出したユーザーを返します。

    トリガーおよびイベントには、SQL SECURITY 特性を定義するためのオプションがありません。したがって、このようなオブジェクトの場合、CURRENT_USER() はオブジェクトを定義したユーザーのアカウントを返します。呼び出したユーザーを返すには、USER() または SESSION_USER() を使用します。

    次のステートメントでは、影響を受けるユーザーや定義したユーザーの名前 (ホストの可能性もあります) の代わりに、CURRENT_USER() 関数を使用することがサポートされています。このような場合、必要に応じて CURRENT_USER() が拡張されます。

    • DROP USER

    • RENAME USER

    • GRANT

    • REVOKE

    • CREATE FUNCTION

    • CREATE PROCEDURE

    • CREATE TRIGGER

    • CREATE EVENT

    • CREATE VIEW

    • ALTER EVENT

    • ALTER VIEW

    • SET PASSWORD

    このような CURRENT_USER() の拡張がさまざまな MySQL 5.6 リリースのレプリケーションで持つ意味については、セクション17.4.1.7「CURRENT_USER() のレプリケーション」を参照してください。

  • DATABASE()

    デフォルト (現在) のデータベース名を utf8 文字セット内の文字列として返します。デフォルトのデータベースがない場合は、DATABASE()NULL を返します。ストアドルーチン内では、デフォルトのデータベースはルーチンが関連付けられたデータベースですが、これは呼び出し元のコンテキストでのデフォルトのデータベースと同じであるとはかぎりません。

    mysql> SELECT DATABASE();
            -> 'test'
    

    デフォルトのデータベースがない場合は、DATABASE()NULL を返します。

  • FOUND_ROWS()

    サーバーからクライアントに返される行の数を制限するために、SELECT ステートメントに LIMIT 句が含まれている場合があります。場合によっては、ステートメントを再度実行せずに、LIMIT を付けなかった場合にステートメントで返されるはずの行数を知っておくことが望ましいことがあります。この行数を取得するには、SELECT ステートメントに SQL_CALC_FOUND_ROWS オプションを付けてから、FOUND_ROWS() を呼び出します。

    mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
        -> WHERE id > 100 LIMIT 10;
    mysql> SELECT FOUND_ROWS();
    

    2 番目の SELECT は、1 番目の SELECTLIMIT 句なしで記述した場合に返される行数を示す数字を返します。

    最近成功した SELECT ステートメントに SQL_CALC_FOUND_ROWS オプションを付けなければ、FOUND_ROWS() は、そのステートメントで返された結果セットの行数を返します。ステートメントに LIMIT 句が含まれている場合、FOUND_ROWS() はその制限値以下の行数を返します。たとえば、ステートメントに LIMIT 10 または LIMIT 50, 10 が含まれている場合、FOUND_ROWS() はそれぞれ 10 と 60 を返します。

    FOUND_ROWS() から取得できる行数は一時的なもので、SELECT SQL_CALC_FOUND_ROWS ステートメントのあとに、このステートメントを発行しても取得できるようには設計されていません。あとで値を参照する必要がある場合は、保存してください。

    mysql> SELECT SQL_CALC_FOUND_ROWS * FROM ... ;
    mysql> SET @rows = FOUND_ROWS();
    

    SELECT SQL_CALC_FOUND_ROWS を使用している場合は、MySQL では完全な結果セット内の行数を計算する必要があります。ただし、結果セットはクライアントに送信される必要がないため、LIMIT なしでクエリーを再度実行するよりも速くなります。

    SQL_CALC_FOUND_ROWS および FOUND_ROWS() は、クエリーで返される行数を制限するが、クエリーを再度実行しないで完全な結果セット内の行数を確認する必要がある状況でも役立ちます。例として、検索結果のほかのセクションを表示するページへのリンクを含むページが表示される Web スクリプトがあります。FOUND_ROWS() を使用すると、残りの結果を表示するために必要なその他のページ数を確認できます。

    SQL_CALC_FOUND_ROWS および FOUND_ROWS() を使用すると、UNION の複数箇所で LIMIT が発生する可能性があるため、単純な SELECT ステートメントよりも、UNION ステートメントで使用した方が複雑になります。これは、UNION 内の個々の SELECT ステートメントに適用される場合と、UNION の結果全体にグローバルに適用される場合があります。

    UNIONSQL_CALC_FOUND_ROWS を使用する目的は、グローバルな LIMIT なしで返される行数を返すことです。UNIONSQL_CALC_FOUND_ROWS を使用する条件は、次のとおりです。

    • UNION の 1 番目の SELECT に、SQL_CALC_FOUND_ROWS キーワードが表示される必要があります。

    • FOUND_ROWS() の値は、UNION ALL が使用されている場合にのみ正確です。ALL なしで UNION が使用される場合は、重複の削除が発生し、FOUND_ROWS() の値が単なる近似値になります。

    • UNIONLIMIT が表示されない場合は、SQL_CALC_FOUND_ROWS が無視され、UNION を処理するために作成された一時テーブル内の行数が返されます。

    ここで説明した以外のケースでは、FOUND_ROWS() の動作 (エラーが発生して SELECT ステートメントに失敗したあとの値など) が定義されません。

    重要

    ステートメントベースのレプリケーションでは、確実に FOUND_ROWS() をレプリケートすることはできません。行ベースのレプリケーションを使用すると、この関数は自動的にレプリケートされます。

  • LAST_INSERT_ID()LAST_INSERT_ID(expr)

    LAST_INSERT_ID() に引数を付けない場合は、最近実行された INSERT ステートメントの結果として、最初に自動的に生成され、正常に AUTO_INCREMENT カラムに挿入された値を表す 64 ビット値が返されます。この値の型は、MySQL 5.6.9 の時点では BIGINT UNSIGNED、それよりも前では BIGINT (符号付き) です。正常に挿入された行がない場合は、LAST_INSERT_ID() の値は未変更のままです。

    LAST_INSERT_ID() に引数を付けない場合は、MySQL 5.6.9 の時点では符号なし整数、それよりも前では符号付き整数が返されます。

    たとえば、AUTO_INCREMENT 値を生成する行を挿入したあとは、次のようにして値を取得できます。

    mysql> SELECT LAST_INSERT_ID();
            -> 195
    

    現在実行中のステートメントによって、LAST_INSERT_ID() の値は影響を受けません。1 つのステートメントで AUTO_INCREMENT 値を生成してから、独自の AUTO_INCREMENT カラムを含むテーブルに行を挿入する複数行の INSERT ステートメントで LAST_INSERT_ID() を参照すると仮定します。LAST_INSERT_ID() の値は、2 番目のステートメントでも未変更のままです。2 番目以降の行でも、その値は以前に行われた行の挿入による影響を受けません。(ただし、LAST_INSERT_ID()LAST_INSERT_ID(expr) への参照を混在させると、効果は定義されません。)

    以前のステートメントでエラーが返された場合は、LAST_INSERT_ID() の値が定義されません。トランザクションテーブルでは、エラーによってステートメントがロールバックされる場合、LAST_INSERT_ID() の値は未定義のままです。手動の ROLLBACK では、LAST_INSERT_ID() の値はトランザクション前の値にリストアされず、ROLLBACK 時点と同じままです。

    MySQL 5.6.15 よりも前では、レプリケーションのフィルタ処理ルールが使用されている場合に、この関数が正常にレプリケートされませんでした。(Bug #17234370、Bug #69861)

    ストアドルーチン (プロシージャーや関数) またはトリガーの本文内では、LAST_INSERT_ID() の値は、このような種類のオブジェクトの本文外で実行されたステートメントと同様に変更されます。あとに続くステートメントで参照される LAST_INSERT_ID() の値でのストアドルーチンまたはトリガーの効果は、ルーチンの種類によって異なります。

    • ストアドプロシージャーで LAST_INSERT_ID() の値を変更するステートメントが実行される場合は、プロシージャー呼び出しが続くステートメントで変更された値が参照されます。

    • 値を変更するストアドファンクションおよびトリガーでは、値は関数やトリガーが終了したときにリストアされ、あとに続くステートメントでは変更された値が参照されません。

    生成された ID は、接続ごとにサーバー内に保持されます。つまり、関数によって指定されたクライアントに返された値は、そのクライアントによって AUTO_INCREMENT カラムに影響を与える最近のステートメント用に最初に生成された AUTO_INCREMENT 値です。この値は、ほかのクライアントが独自の AUTO_INCREMENT 値を生成した場合でも影響を受ける可能性はありません。この動作によって、各クライアントはほかのクライアントのアクティビティーを気にすることなく、ロックやトランザクションを実行しないで独自の ID を取得できます。

    行の AUTO_INCREMENT カラムを非マジック値 (つまり、NULL でも 0 でもない値) に設定する場合は、LAST_INSERT_ID() の値が変更されません。

    重要

    単一の INSERT ステートメントを使用して複数の行を挿入する場合、LAST_INSERT_ID() は、最初に挿入された行のみに対して生成された値を返します。この理由は、ほかの一部のサーバーに対して同じ INSERT ステートメントを簡単に再現できるようにするためです。

    例:

    mysql> USE test;
    Database changed
    mysql> CREATE TABLE t (
        ->   id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
        ->   name VARCHAR(10) NOT NULL
        -> );
    Query OK, 0 rows affected (0.09 sec)
    
    mysql> INSERT INTO t VALUES (NULL, 'Bob');
    Query OK, 1 row affected (0.01 sec)
    
    mysql> SELECT * FROM t;
    +----+------+
    | id | name |
    +----+------+
    |  1 | Bob  |
    +----+------+
    1 row in set (0.01 sec)
    
    mysql> SELECT LAST_INSERT_ID();
    +------------------+
    | LAST_INSERT_ID() |
    +------------------+
    |                1 |
    +------------------+
    1 row in set (0.00 sec)
    
    mysql> INSERT INTO t VALUES
        -> (NULL, 'Mary'), (NULL, 'Jane'), (NULL, 'Lisa');
    Query OK, 3 rows affected (0.00 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> SELECT * FROM t;
    +----+------+
    | id | name |
    +----+------+
    |  1 | Bob  |
    |  2 | Mary |
    |  3 | Jane |
    |  4 | Lisa |
    +----+------+
    4 rows in set (0.01 sec)
    
    mysql> SELECT LAST_INSERT_ID();
    +------------------+
    | LAST_INSERT_ID() |
    +------------------+
    |                2 |
    +------------------+
    1 row in set (0.00 sec)
    

    2 番目の INSERT ステートメントで 3 つの新しい行が t に挿入されましたが、これらの行の 1 番目に生成された ID は 2 であり、あとに続く SELECT ステートメントでも、この値が LAST_INSERT_ID() によって返されます。

    INSERT IGNORE を使用し、その行が無視された場合、LAST_INSERT_ID() は現在の値から未変更のままです (接続で正常な INSERT が実行されていない場合は、0 が返されます)。トランザクショナル以外のテーブルでは、AUTO_INCREMENT カウンタが増分されません。InnoDB テーブルでは、innodb_autoinc_lock_mode1 または 2 に設定されている場合は、次の例で示すように AUTO_INCREMENT が増分されます。

    mysql> USE test;
    Database changed
    
    mysql> SELECT @@innodb_autoinc_lock_mode;
    +----------------------------+
    | @@innodb_autoinc_lock_mode |
    +----------------------------+
    |                          1 |
    +----------------------------+
    1 row in set (0.00 sec)
    
    mysql> CREATE TABLE `t` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `val` INT(11) DEFAULT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `i1` (`val`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    Query OK, 0 rows affected (0.02 sec)
    
    -- Insert two rows
    
    mysql> INSERT INTO t (val) VALUES (1),(2);
    Query OK, 2 rows affected (0.00 sec)
    Records: 2  Duplicates: 0  Warnings: 0
    
    -- With auto_increment_offset=1, the inserted rows
    -- result in an AUTO_INCREMENT value of 3
    
    mysql> SHOW CREATE TABLE t\G
    *************************** 1. row ***************************
           Table: t
    Create Table: CREATE TABLE `t` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `val` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `i1` (`val`)
    ) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
    1 row in set (0.00 sec)
    
    -- LAST_INSERT_ID() returns the first automatically generated 
    -- value that is successfully inserted for the AUTO_INCREMENT column
    
    mysql> SELECT LAST_INSERT_ID();
    +------------------+
    | LAST_INSERT_ID() |
    +------------------+
    |                1 |
    +------------------+
    1 row in set (0.00 sec)
    
    -- The attempted insertion of duplicate rows fail but errors are ignored     
    
    mysql> INSERT IGNORE INTO t (val) VALUES (1),(2);
    Query OK, 0 rows affected (0.00 sec)
    Records: 2  Duplicates: 2  Warnings: 0
    
    -- With innodb_autoinc_lock_mode=1, the AUTO_INCREMENT counter 
    -- is incremented for the ignored rows
    
    mysql> SHOW CREATE TABLE t\G
    *************************** 1. row ***************************
           Table: t
    Create Table: CREATE TABLE `t` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `val` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `i1` (`val`)
    ) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
    1 row in set (0.00 sec)
    
    -- The LAST_INSERT_ID is unchanged becuase the previous insert was unsuccessful
    
    mysql> SELECT LAST_INSERT_ID();
    +------------------+
    | LAST_INSERT_ID() |
    +------------------+
    |                1 |
    +------------------+
    1 row in set (0.00 sec)        

    詳細は、セクション14.6.5「InnoDB での AUTO_INCREMENT 処理」を参照してください。

    exprLAST_INSERT_ID() への引数として指定されている場合は、その引数の値が関数によって返され、LAST_INSERT_ID() によって次に返される値として記憶されます。これを使用すると、シーケンスのシミュレーションを行うことができます。

    1. シーケンスカウンタを保持するテーブルを作成し、それを初期化します。

      mysql> CREATE TABLE sequence (id INT NOT NULL);
      mysql> INSERT INTO sequence VALUES (0);
      
    2. そのテーブルを使用して、次のようにシーケンス番号を生成します。

      mysql> UPDATE sequence SET id=LAST_INSERT_ID(id+1);
      mysql> SELECT LAST_INSERT_ID();
      

      UPDATE ステートメントは、シーケンスカウンタを増分し、LAST_INSERT_ID() への次の呼び出しで更新された値が返されるようにします。SELECT ステートメントは、その値を取得します。mysql_insert_id() C API 関数を使用して、値を取得することもできます。セクション23.8.7.37「mysql_insert_id()」を参照してください。

    LAST_INSERT_ID() を呼び出さずに、シーケンスを生成できます。このように関数を使用する有用性は、ID 値が最後に自動的に生成された値として保持されることです。独自のシーケンス値を生成するほかのクライアントと互いに影響しあうことなく、複数のクライアントが UPDATE ステートメントを発行し、SELECT ステートメント (または mysql_insert_id()) で独自のシーケンス値を取得できるため、マルチユーザーでも安全です。

    mysql_insert_id() 関数は、INSERT および UPDATE ステートメントのあとにしか更新されないため、SELECTSET などのその他の SQL ステートメントを実行したあとに、この C API 関数を使用しても、LAST_INSERT_ID(expr) の値を取得できません。

  • ROW_COUNT()

    MySQL 5.6 では、ROW_COUNT() は次のように値を返します。

    • DDL ステートメント: 0。これは、CREATE TABLEDROP TABLE などのステートメントに適用されます。

    • SELECT 以外の DML ステートメント: 影響を受ける行数です。これは、(以前と同様に) UPDATEINSERTDELETE などのステートメントに適用されますが、ALTER TABLELOAD DATA INFILE などのステートメントにも適用されるようになりました。

    • SELECT: ステートメントで結果セットが返される場合は -1、そうでない場合は影響を受ける行数。たとえば、SELECT * FROM t1 の場合、ROW_COUNT() は -1 を返します。SELECT * FROM t1 INTO OUTFILE 'file_name' の場合、ROW_COUNT() はファイルに書き込まれた行の数を返します。

    • SIGNAL ステートメント: 0。

    UPDATE ステートメントの場合、デフォルトで影響を受けた行の値は実際に変更された行の数です。mysqld への接続時に CLIENT_FOUND_ROWS フラグを mysql_real_connect() に指定した場合、影響を受けた行の値は見つかった、つまり WHERE 句に一致した行数です。

    REPLACE ステートメントの場合、影響を受けた行の値は、新しい行が古い行に置き換わった場合 2 です。この場合、重複が削除されたあとに行が挿入されたためです。

    INSERT ... ON DUPLICATE KEY UPDATE ステートメントの場合、行ごとの影響を受けた行の値は、その行が新しい行として挿入された場合は 1、既存の行が更新された場合は 2、既存の行がその現在の値に設定された場合は 0 です。CLIENT_FOUND_ROWS フラグを指定した場合、影響を受けた行の値は、既存の行がその現在の値に設定された場合は (0 ではなく) 1 になります。

    ROW_COUNT() は、mysql_affected_rows() C API 関数から取得される値と同様で、ステートメントの実行後に mysql クライアントに表示される行数です。

    mysql> INSERT INTO t VALUES(1),(2),(3);
    Query OK, 3 rows affected (0.00 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> SELECT ROW_COUNT();
    +-------------+
    | ROW_COUNT() |
    +-------------+
    |           3 |
    +-------------+
    1 row in set (0.00 sec)
    
    mysql> DELETE FROM t WHERE i IN(1,2);
    Query OK, 2 rows affected (0.00 sec)
    
    mysql> SELECT ROW_COUNT();
    +-------------+
    | ROW_COUNT() |
    +-------------+
    |           2 |
    +-------------+
    1 row in set (0.00 sec)
    
    重要

    ステートメントベースのレプリケーションでは、確実に ROW_COUNT() をレプリケートすることはできません。行ベースのレプリケーションを使用すると、この関数は自動的にレプリケートされます。

  • SCHEMA()

    この関数は DATABASE() のシノニムです。

  • SESSION_USER()

    SESSION_USER()USER() のシノニムです。

  • SYSTEM_USER()

    SYSTEM_USER()USER() のシノニムです。

  • USER()

    現在の MySQL ユーザー名とホスト名を utf8 文字セット内の文字列として返します。

    mysql> SELECT USER();
            -> 'davida@localhost'
    

    この値は、サーバーへの接続時に指定したユーザー名および接続元のクライアントホストを示します。CURRENT_USER() の値とは異なる可能性があります。

    次のように、ユーザー名の部分のみを抽出できます。

    mysql> SELECT SUBSTRING_INDEX(USER(),'@',1);
            -> 'davida'
    
  • VERSION()

    MySQL サーバーのバージョンを示す文字列を返します。この文字列では、utf8 文字セットが使用されます。値にはバージョン番号に加えて、サフィクスが付いている場合もあります。セクション5.1.4「サーバーシステム変数」内の version システム変数の説明を参照してください。

    この関数は、ステートメントベースのレプリケーションでは安全に使用できません。binlog_formatSTATEMENT に設定されているときに、この関数を使用すると、警告のログが記録されます。

    mysql> SELECT VERSION();
            -> '5.6.23-standard'
    

User Comments
  Posted by Tom Andresen on June 28, 2005
I was issuing my query "select sql_calc_found_rows statement1 union statement2 union statement3 limit whatever" and getting a count from found_rows() that was incorrect. It was running as if I had run the query as "union all" because it was returning duplicates. After rereading the union syntax page I reissued the query with parens around each individual statement. "(select sql_calc_found_rows statement1) union (statement2) union (statement3) limit whatever" This yielded the expected result.
  Posted by Chr. Ludwig on September 8, 2005
Hi,
if you want to perform a complex benchmark, you need to put doble quotes around your expression:

SELECT BENCHMARK(1000000, "ENCODE('hello','goodbye')");

And remember to but a SELECT in front of BENCHMARK.
  Posted by H Y on January 2, 2006
The above reads "If the preceding SELECT statement does not include the SQL_CALC_FOUND_ROWS option, then FOUND_ROWS() may return a different result when LIMIT is used than when it is not."

The word "may" seems to be an understatement. Everytime I run a SELECT with LIMIT, FOUND_ROWS() returns whatever number I put after LIMIT. E.g. after

SELECT * FROM table LIMIT 50

FOUND_ROWS() will return 50.

But if I do

SELECT * FROM table LIMIT 10, 10,

FOUND_ROWS() will return 20 though. :)

This is annoying, since I need this information from a 20,000-row table fulltext search, and a 0,008 second search then suddenly takes about 20 seconds... Haven't found a workaround yet...
  Posted by Danny Swett on March 11, 2006
This is the desired result though, as:

SELECT * FROM table LIMIT 50

FOUND_ROWS() will return 50 cause it actually found 50 entries in the table before it stopped and returned the result

But if I do

SELECT * FROM table LIMIT 10, 10,

FOUND_ROWS() will return 20 cause it had to find the first 10 you skipped over, then the second 10 it returned to you, so it found 20 entries before stopping and giving you the result

  Posted by Wade Bowmer on May 14, 2006
Be aware that using SQL_CALC_FOUND_ROWS and FOUND_ROWS() disables ORDER BY ... LIMIT optimizations (see bugs http://bugs.mysql.com/bug.php?id=18454 and http://bugs.mysql.com/bug.php?id=19553). Until it's fixed, you should run your own benchmarks with and without it.

  Posted by Paul Lautman on May 16, 2006
The text says "include a SQL_CALC_FOUND_ROWS option in the SELECT statement". What it doesn't say is that SQL_CALC_FOUND_ROWS must be at the front of any fields in the SELECT statement!
  Posted by Andrew Purdon on June 19, 2006
An alternative to the previously discussed issue:

SELECT * FROM table LIMIT 10, 10,
FOUND_ROWS() will return 20

If rows are counted from the client, the "expected" number of rows can be calcualted. This, of course, requires that the result set is passed to the client.
  Posted by Roman Okoyomov on October 1, 2006
about "LIMIT 10,10" issue...

manual says:
"... The intent of SQL_CALC_FOUND_ROWS for UNION is that it should return the row count that would be returned without a global LIMIT."

though that means 'select * from tableX limit 50' returns 50 as a result of 'Found_rows()' just because tableX has 50 records, and 'select * from tableX limit 10,10' will return also 50 and not 10 or 20 as a result!

and don't forget use SQL_CALC_FOUND_ROWS modifier.
  Posted by Jeffrey Binder on December 22, 2010
If you are using the Python MySQLdb module, bear in mind that inserting multiple rows with executemany() does NOT count as a single operation for the purpose of last_insert_id(). The value returned (assuming success) will be the ID created for the LAST row in the list.
  Posted by Lior Ben-Kereth on March 30, 2011
Using the LAST_INSERT_ID() to simulate a sequence as suggested above, will not work well when table is replicated, and access is randomly made for one of the replicated servers.
To overcome this, one can use this method:
1) Create a table with two columns: First is auto_incremented primary key. The second, is unique int.

CREATE TABLE IF NOT EXISTS `sequence` (
`id` int(11) NOT NULL auto_increment,
`value` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `value` (`value`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

2) Then, use the replace statement to increment the id column. (The unique index on value makes sure that the single row is being deleted and new one is inserted)
REPLACE INTO `sequence` set value=1

3) Use LAST_INSERT_ID() to get the newly inserted Id.

Now, using the auto_increment_offset and the auto_increment_increment server varaiables listed here, http://dev.mysql.com/doc/refman/5.0/en/replication-options-master.html#sysvar_auto_increment_increment, you can make sure that auto increment values on the replicated machines will not overlap (i.e odd, and even), and the sequence will work smoothly.

Lior Ben-Kereth

  Posted by Hector Guilarte on April 10, 2012
When using SELECT LAST_INSERT_ID() keep in mind that it does not need the FROM <Table> part of the query.

I know this might sound obvious, but I had huge performance problems on a production database just because of putting the "FROM".

Here is the blog post that helped me fix the issue on my code: http://uwstopia.nl/blog/2009/02/mysql-last-insert-id-performance-issues

  Posted by Peter Bagnall on June 1, 2012
Despite the warning above "you cannot use the C API function to retrieve the value for LAST_INSERT_ID(expr) after executing other SQL statements like SELECT or SET" it seems that in actual fact you can. This was certainly correct in 5.0, but 5.5 appears to have removed this limitation.
  Posted by Kai Pfeiffer on May 18, 2013
I had the problem, that I retrieved a negative result like "-1" when I triggered a ROW_COUNT() after executing a prepared statement.

My mistake was, that I deallocated the statement before I executed ROW_COUNT().

Example 1:
1. EXECUTE statement
2. DEALLOCATE statement
3. ROW_COUNT()
doesn't work.

Example 2:
1. EXECUTE statement,
2. ROW_COUNT()
3. DEALLOCATE statement
works like expected

It might be trivial, but I searched the whole web for this solution and I found none.
  Posted by Piotr SaÅ‚aciak on November 18, 2013
If You would like to get current auto_increment value for certain table You can use this query. Just one note: it's insecure to let remote user to have access to information_schema, so try to execute this with some separated local user.

SELECT AUTO_INCREMENT FROM information_schema.`TABLES`
WHERE `table_schema` = 'DATABASE_NAME' AND `table_name` = 'TABLE_NAME';
Sign Up Login You must be logged in to post a comment.