名前 | 説明 |
---|---|
BENCHMARK() |
式を繰り返し実行します |
CHARSET() (v4.1.0) |
引数のキャラクタセットを返します |
COERCIBILITY() (v4.1.1) |
文字列引数の照合強制性値を返します |
COLLATION() (v4.1.0) |
文字列引数の照合を返します |
CONNECTION_ID() |
接続のコネクション ID (スレッド ID) を返します |
CURRENT_USER() 、CURRENT_USER |
認証済みのユーザー名とホスト名 |
DATABASE() |
デフォルトの (現在の) データベース名を返します |
FOUND_ROWS() |
LIMIT 節を含む SELECT で、その LIMIT 節がなかった場合に返されるであろう行数 |
LAST_INSERT_ID() |
前回の INSERT での AUTOINCREMENT カラムの値 |
ROW_COUNT() (v5.0.1) |
更新された行の数 |
SCHEMA() (v5.0.2) |
DATABASE() の同義語 |
SESSION_USER() |
USER() の同義語 |
SYSTEM_USER() |
USER() の同義語 |
USER() |
クライアントから提供されたユーザー名とホスト名 |
VERSION() |
MySQL サーバーのバージョンを示す文字列を返します |
BENCHMARK()
関数は、式 expr
を
count
の回数だけ繰り返し実行します。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()
はスカラー式の実行時パフォーマンスを測定するためのものですが、その動作は、その使用方法や結果の解釈方法に関するいくつかの重要な前提に基づいています。
使用できるのはスカラー式だけです。式としてサブクエリーを指定することも可能ですが、サブクエリーから返されるカラム数は
1 個、行数も多くて 1
行でなければなりません。たとえば、テーブル
t
に複数のカラムや行が含まれていると、BENCHMARK(10,
(SELECT * FROM t))
は失敗します。
SELECT
ステートメントを expr
N
回実行する場合と、SELECT
BENCHMARK(
を実行する場合とでは、発生するオーバーヘッドの量が異なります。この
2
つは非常に異なる実行プロファイルを持つため、両者の所要時間が同じになると期待すべきではありません。前者ではパーサーの処理、オプティマイザの処理、テーブルロック、および実行時評価がそれぞれ
N
,
expr
)N
回ずつ発生します。後者では、N
回発生するのは実行時評価のみであり、その他の要素はすべて
1
回だけ発生します。すでに割り当て済みのメモリー構造体は再利用されますし、集約関数ですでに評価済みの結果をローカルにキャッシュするなどの実行時最適化により結果が変わる可能性もあります。したがって、BENCHMARK()
の使用時には実行時要素のパフォーマンスを測定できるよう、その要素により多くの比重が置かれ、ネットワークやパーサー、オプティマイザなどから混入する
「ノイズ」 は除去されます。
文字列引数のキャラクタセットを返します。
mysql>SELECT CHARSET('abc');
-> 'latin1' mysql>SELECT CHARSET(CONVERT('abc' USING utf8));
-> 'utf8' mysql>SELECT CHARSET(USER());
-> 'utf8'
文字列引数の照合型変換値を返します。
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
から引き出された式 |
文字列引数の照合を返します。
mysql>SELECT COLLATION('abc');
-> 'latin1_swedish_ci' mysql>SELECT COLLATION(_utf8'abc');
-> 'utf8_general_ci'
接続のコネクション ID (スレッド ID) を返します。すべての接続は、接続しているクライアントのセットの中で一意となる ID を持っています。
mysql> SELECT CONNECTION_ID();
-> 23786
現在のクライアントの認証にサーバーが使用した
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
の権限テーブルにアカウントリストがないことが挙げられます。
ストアドプログラムやビュー内では、CURRENT_USER()
は、そのオブジェクトを定義したユーザーのアカウント
(その DEFINER
値に指定された情報)
を返します。SQL SECURITY
INVOKER
特性で定義されたストアドプロシージャー、ストアドファンクション、およびビューの場合、CURRENT_USER()
はそのオブジェクトの呼び出し元を返します。
デフォルト (現行の)
データベース名を、utf8
キャラクタセット内の文字列として返します。デフォルトのデータベースがない場合は、DATABASE()
は NULL
を返します。ストアドルーチン内で、デフォルトのデータベースはルーチンが関連するデータベースですが、コーリングコンテキストのデフォルトのデータベースと同様である必要はありません。
mysql> SELECT DATABASE();
-> 'test'
デフォルトのデータベースがない場合は、DATABASE()
は NULL
を返します。
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
は、最初の
SELECT
が返した、LIMIT
節なしで書かれた行数を示す数字を返します。
もっとも最近の成功
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()
は、クエリーが戻す行の数を制限する際に便利ですが、クエリーを再度実行することなく完全な結果セットの行の数を決定するためにも利用できます。検索結果のほかの節を表示するページへのリンクを含む、ページ表示を提示するウェブスクリプトが例に挙げられます。FOUND_ROWS()
を使用することで、残りの結果がさらに何ページを必要とするかを決定することができます。
SQL_CALC_FOUND_ROWS
および
FOUND_ROWS()
の使用は、UNION
の複数箇所で
LIMIT
が起こる場合があるため、簡単な
SELECT
ステートメントよりも、UNION
ステートメントに対してのほうがより複雑になります。これは、UNION
の個々の
SELECT
ステートメントに用いられるか、または
UNION
結果全体にグローバルに適用されます。
UNION
に対する
SQL_CALC_FOUND_ROWS
の目的は、グローバルな
LIMIT
なしで返される行数を返すことです。UNION
との
SQL_CALC_FOUND_ROWS
の使用の条件は以下 :
SQL_CALC_FOUND_ROWS
キーワードが、UNION
の最初の
SELECT
に表示されている。
UNION ALL
が使用されている場合のみ、FOUND_ROWS()
の値は正確。ALL
なしで UNION
が使用される場合は、複製が除去され、FOUND_ROWS()
の値は近似のみになる。
UNION
で
LIMIT
が提示されない場合、SQL_CALC_FOUND_ROWS
は無視され、UNION
を処理するために作成された一時テーブルの行の数を返す。
ここで説明した場合以外の
FOUND_ROWS()
の動作 (エラーが発生して失敗した
SELECT
ステートメントのあとでのその値など)
は、未定義となります。
ステートメントベースのレプリケーションでは、FOUND_ROWS()
は確実に複製されません。MySQL 5.1.23
以降では、この関数は行ベースのレプリケーションで自動的に複製されます。
LAST_INSERT_ID()
,
LAST_INSERT_ID(
expr
)
MySQL 5.1.12
以降では、LAST_INSERT_ID()
(引数なし) は、もっとも最近に実行された
INSERT
ステートメントの結果として
AUTO_INCREMENT
カラムに正常に
インサートされた、自動的に生成された最初の値を返します。LAST_INSERT_ID()
の値は、正常にインサートされた行がない場合は、未変更のままになります。
たとえば、AUTO_INCREMENT
値を生成する行をインサートしたあとは、次のようにして値を得ることができます
:
mysql> SELECT LAST_INSERT_ID();
-> 195
MySQL 5.1.11
以前では、LAST_INSERT_ID()
(引数なし)
は、行が正常にインサート、または更新された場合、自動低に生成された最初の値を返します。つまり、戻された値は、テーブルに正常にインサートされなかった値である可能性があります。正常にインサートされた行がなければ、LAST_INSERT_ID()
は 0 を返します。
LAST_INSERT_ID()
の値は、INSERT
または
UPDATE
ステートメントのすべての行が正常である場合、全バージョンにわたって一貫するでしょう。
テーブルに
AUTO_INCREMENT
カラムが含まれていて、INSERT
... ON DUPLICATE KEY UPDATE
によって行が
(挿入ではなく)
更新される場合、LAST_INSERT_ID()
の値は、MySQL 5.1.12
より前のバージョンでは無意味となります。その回避方法については、項8.2.5.3. 「INSERT
... ON DUPLICATE KEY UPDATE
構文」を参照してください。
実行中のステートメントが、LAST_INSERT_ID()
の値に影響をおよぼすことはありません。ひとつのステートメントで
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
時点と同じまま残ります。
ストアドルーチン
(プロシージャーまたは関数)
またはトリガーのボディ内で、LAST_INSERT_ID()
の値は、これらの種類のオブジェクトの外で実行されたステートメントと同様に変化します。後に続くステートメントに参照される
LAST_INSERT_ID()
の値に基づくストアドルーチンまたはトリガーの効果は、ルーチンの種類によって異なります
:
ストアドプロシージャーが
LAST_INSERT_ID()
の値を変えるステートメントを実行する場合、変更された値はプロシージャー呼び出しに従うステートメントによって参照されます。
値を変更するストアドファンクションやトリガーでは、値は関数やトリガーが終了したときに復元され、続くステートメントは変更された値を参照しません。
生成された ID
は、接続ベースで
サーバー内で保持されます。つまり、関数によって指定のクライアントに戻された値は、そのクライアントによって
AUTO_INCREMENT
カラムに影響を及ぼすもっとも最近のステートメントのために生成された、最初の
AUTO_INCREMENT
値です。この値は、ほかのクライアントが独自の
AUTO_INCREMENT
値を生成した場合でも、ほかのクライアントによって影響を受けることはありません。この動作は、各クライアントがほかのクライアントの動向を気にせず、ロックやトランザクションなしで、独自の
ID を呼び出せるようにします。
行の
AUTO_INCREMENT
カラムを非 「magic」 値
(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
を使用して行を無視する場合は、AUTO_INCREMENT
カウンタは増分されず、行がインサートされなかったことを反映して、LAST_INSERT_ID()
は 0
を返します。
expr
が
LAST_INSERT_ID()
への引数として与えられる場合、その引数の値は関数によって戻され、LAST_INSERT_ID()
によって戻される次の値として記憶されます。これによってシークエンスのシミュレーションをすることも可能です
:
テーブルを作成してシークエンスカウンタを保留にし、初期化 :
mysql>CREATE TABLE sequence (id INT NOT NULL);
mysql>INSERT INTO sequence VALUES (0);
テーブルを使用して、次のようにシークエンス番号を生成 :
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
関数は、値の入手に使用することもできます。mysql_insert_id()
を参照してください。
LAST_INSERT_ID()
を呼び出さずにシークエンスを生成することはできますが、このように関数を使用することの利点は、ID
値が自動的に生成された最後の値として保持されることです。独自のシークエンス値を生成するほかのクライアントと互いに影響しあうことなく、複数のクライアントが
UPDATE
ステートメントを発行し、UPDATE
ステートメント (または
mysql_insert_id()
)
でそれぞれのシークエンス値を取得することができるため、マルチユーザーでも安全です。
mysql_insert_id()
は INSERT
および
UPDATE
ステートメントの後にのみ更新され、SELECT
または SET
のようなほかの SQL
ステートメントを実行したあとに、C API
関数を使用して
LAST_INSERT_ID(
の値を引き出すことはできないのでご注意ください。
expr
)
ROW_COUNT()
は、先行するステートメントによって更新、インサート、または削除された行の数を返します。これは
mysql
クライアントが表示する行のカウントおよび、mysql_affected_rows()
C API 関数からの値と同じです。
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()
は確実に複製されません。MySQL 5.1.23
以降では、この関数は行ベースのレプリケーションで自動的に複製されます。(Bug#30244)
この関数は
DATABASE()
の同義語です。
SESSION_USER()
は USER()
の同義語です。
SYSTEM_USER()
は USER()
の同義語です。
現行の MySQL
ユーザー名とホスト名を、utf8
キャラクタセット内の文字列として返します。
mysql> SELECT USER();
-> 'davida@localhost'
その値はサーバーへの接続時に指定したユーザー名と、接続したホストからのクライアントを示します。値は
CURRENT_USER()
によって異なる場合があります。
次のように、ユーザー名の部分だけを摘出することができます :
mysql> SELECT SUBSTRING_INDEX(USER(),'@',1);
-> 'davida'
MySQL
サーバーのバージョンを示す文字列を返します。その文字列は、utf8
キャラクタセットを使用します。
mysql> SELECT VERSION();
-> '5.1.47-standard'
-log
で終わるバージョン文字列は、ロギングが有効になっていることを表しています。