This chapter describes the syntax for the SQL statements supported in MySQL.
DELETE
SyntaxDELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM table_name [WHERE where_definition] [ORDER BY ...] [LIMIT row_count]
or:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] table_name[.*] [, table_name[.*] ...] FROM table-references [WHERE where_definition]
or:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM table_name[.*] [, table_name[.*] ...] USING table-references [WHERE where_definition]
DELETE
deletes rows from table_name
that satisfy the condition
given by where_definition
, and returns the number of records deleted.
If you issue a DELETE
with no WHERE
clause, all rows are
deleted. If you do this in AUTOCOMMIT
mode, this works as
TRUNCATE
. See section 13.1.9 TRUNCATE
Syntax. In MySQL 3.23,
DELETE
without a WHERE
clause will return zero as the number
of affected records.
If you really want to know how many records are deleted when you are deleting
all rows, and are willing to suffer a speed penalty, you can use a
DELETE
statement of this form:
mysql> DELETE FROM table_name WHERE 1>0;
Note that this is much slower than DELETE FROM table_name
with no
WHERE
clause, because it deletes rows one at a time.
If you specify the keyword LOW_PRIORITY
, execution of the
DELETE
is delayed until no other clients are reading from the table.
For MyISAM tables,
if you specify the word QUICK
then the storage engine will not
merge index leaves during delete, which may speed up certain kind of
deletes.
The speed of delete operations may also be affected by factors discussed in
section 7.2.13 Speed of DELETE
Queries.
Option IGNORE
causes MySQL to ignore all errors during the process of
deleting rows. Errors encountered during the parsing stage are processed
in the usual manner. Errors that are ignored due to the use of this option
are returned as warnings. This option first appeared in version 4.1.1.
In MyISAM
tables, deleted records are maintained in a linked list and
subsequent INSERT
operations reuse old record positions. To
reclaim unused space and reduce file-sizes, use the OPTIMIZE
TABLE
statement or the myisamchk
utility to reorganize tables.
OPTIMIZE TABLE
is easier, but myisamchk
is faster. See
section 13.5.2.5 OPTIMIZE TABLE
Syntax and section 5.5.2.10 Table Optimization.
The first multiple-table delete format is supported starting from MySQL 4.0.0. The second multiple-table delete format is supported starting from MySQL 4.0.2.
The idea is that only matching rows from the tables listed
before the FROM
or before the USING
clause are
deleted. The effect is that you can delete rows from many tables at the
same time and also have additional tables that are used for searching.
The .*
after the table names is there just to be compatible with
Access
:
DELETE t1,t2 FROM t1,t2,t3 WHERE t1.id=t2.id AND t2.id=t3.id
or:
DELETE FROM t1,t2 USING t1,t2,t3 WHERE t1.id=t2.id AND t2.id=t3.id
In the above case we delete matching rows only from tables t1
and
t2
.
The examples show inner joins using the comma operator, but
multiple-table DELETE
statements can use any type of
join allowed in SELECT
statements, such as LEFT JOIN
.
If an ORDER BY
clause is used (available from MySQL 4.0.0), the rows
will be deleted in that order. This is really only useful in conjunction
with LIMIT
. For example:
DELETE FROM somelog WHERE user = 'jcole' ORDER BY timestamp LIMIT 1
This will delete the oldest entry (by timestamp
) where the row matches
the WHERE
clause.
The MySQL-specific LIMIT row_count
option to DELETE
tells
the server the maximum number of rows to be deleted before control is
returned to the client. This can be used to ensure that a specific
DELETE
command doesn't take too much time. You can simply repeat
the DELETE
command until the number of affected rows is less than
the LIMIT
value.
From MySQL 4.0, you can specify multiple tables in the DELETE
statement to delete rows from one or more tables depending on a particular
condition in multiple tables. However, you cannot use ORDER BY
or LIMIT
in a multiple-table DELETE
.
DO
SyntaxDO expression, [expression, ...]
Execute the expression but don't return any results. This is a
shorthand of SELECT expression, expression
, but has the advantage
that it's slightly faster when you don't care about the result.
This is mainly useful with functions that has side effects, like
RELEASE_LOCK
.
HANDLER
SyntaxHANDLER tbl_name OPEN [ AS alias ] HANDLER tbl_name READ index_name { = | >= | <= | < } (value1,value2,...) [ WHERE ... ] [LIMIT ... ] HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST } [ WHERE ... ] [LIMIT ... ] HANDLER tbl_name READ { FIRST | NEXT } [ WHERE ... ] [LIMIT ... ] HANDLER tbl_name CLOSE
The HANDLER
statement provides direct access to the MyISAM
table
storage engine interface.
The first form of HANDLER
statement opens a table, making
it accessible via subsequent HANDLER ... READ
statements.
This table object is not shared by other threads and will not be closed
until the thread calls HANDLER tbl_name CLOSE
or the thread dies.
The second form fetches one row (or more, specified by LIMIT
clause) where the index specified satisfies the given values and the
WHERE
condition is met. If you have a multiple-column index,
specify the index column values as a comma-separated list. Either specify
values for all the columns in the index, or specify values for a leftmost
prefix of the index columns. Suppose an index includes three columns
named col_a
, col_b
, and col_c
, in that order.
The HANDLER
statement can specify values for all three columns in the
index, or for the columns in a leftmost prefix. For example:
HANDLER ... index_name = (col_a_val,col_b_val,col_c_val) ... HANDLER ... index_name = (col_a_val,col_b_val) ... HANDLER ... index_name = (col_a_val) ...
The third form fetches one row (or more, specified by LIMIT
clause)
from the table in index order, matching WHERE
condition.
The fourth form (without index specification) fetches one row (or more, specified
by LIMIT
clause) from the table in natural row order (as stored
in datafile) matching WHERE
condition. It is faster than
HANDLER tbl_name READ index_name
when a full table scan is desired.
HANDLER ... CLOSE
closes a table that was opened with
HANDLER ... OPEN
.
Note: If you're using HANDLER
interface for PRIMARY KEY
you should
remember to quote the keyword PRIMARY with backticks:
HANDLER tbl READ `PRIMARY` > (...)
HANDLER
is a somewhat low-level statement. For example, it does
not provide consistency. That is, HANDLER ... OPEN
does NOT
take a snapshot of the table, and does NOT lock the table. This
means that after a HANDLER ... OPEN
is issued, table data can be
modified (by this or any other thread) and these modifications may appear
only partially in HANDLER ... NEXT
or HANDLER ... PREV
scans.
The reasons to use this interface instead of normal SQL are:
SELECT
because:
HANDLER OPEN
.
INSERT
SyntaxINSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name [(col_name,...)] VALUES ((expression | DEFAULT),...),(...),... [ ON DUPLICATE KEY UPDATE col_name=expression, ... ] or INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name [(col_name,...)] SELECT ... or INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name SET col_name=(expression | DEFAULT), ... [ ON DUPLICATE KEY UPDATE col_name=expression, ... ]
INSERT
inserts new rows into an existing table. The INSERT
... VALUES
form of the statement inserts rows based on explicitly
specified values. The INSERT ... SELECT
form inserts rows
selected from another table or tables. The INSERT ... VALUES
form with multiple value lists is supported in MySQL Version
3.22.5 or later. The col_name=expression
syntax is supported in
MySQL Version 3.22.10 or later.
tbl_name
is the table into which rows should be inserted. The column
name list or the SET
clause indicates which columns the statement
specifies values for:
INSERT ... VALUES
or INSERT
... SELECT
, values for all columns in the table must be provided in the
VALUES()
list or by the SELECT
. If you don't know the order of
the columns in the table, use DESCRIBE tbl_name
to find out.
CREATE TABLE
Syntax.
You can also use the keyword DEFAULT
to set a column to its
default value. (New in MySQL 4.0.3.) This makes it easier to write
INSERT
statements that assign values to all but a few columns,
because it allows you to avoid writing an incomplete VALUES()
list
(a list that does not include a value for each column in the table).
Otherwise, you would have to write out the list of column names
corresponding to each value in the VALUES()
list.
MySQL always has a default value for all fields. This is something
that is imposed on MySQL to be able to work with both transactional
and non-transactional tables.
Our view is that checking of fields content should be done in the
application and not in the database server.
expression
may refer to any column that was set earlier in a value
list. For example, you can say this:
mysql> INSERT INTO tbl_name (col1,col2) VALUES(15,col1*2);But not this:
mysql> INSERT INTO tbl_name (col1,col2) VALUES(col2*2,15);
DELAYED
, the server puts the row or
rows to be inserted into a buffer, and the client issuing the INSERT
DELAYED
statement then may continue on. If the table is busy, the server
holds the rows. When the table becomes free, it begins inserting rows,
checking periodically to see if there are new read requests for the
table. If there are, the delayed row queue is suspended until the table
becomes free again.
LOW_PRIORITY
, execution of the
INSERT
is delayed until no other clients are reading from the
table. This includes other clients that began reading while existing
clients are reading, and while the INSERT LOW_PRIORITY
statement
is waiting. It is possible therefore for a client that issues an
INSERT LOW_PRIORITY
statement to wait for a very long time (or
even forever) in a read-heavy environment.
(This is in contrast to INSERT DELAYED
, which lets the client
continue at once.) See section 13.1.4.2 INSERT DELAYED
Syntax. Note that LOW_PRIORITY
should normally not be used with MyISAM
tables as this disables
concurrent inserts. See section 14.1 MyISAM
Tables.
IGNORE
in an INSERT
with many
rows, any rows that duplicate an existing PRIMARY
or UNIQUE
key in the table are ignored and are not inserted. If you do not specify
IGNORE
, the insert is aborted if there is any row that duplicates an
existing key value. You can determine with the C API function
mysql_info()
how many rows were inserted into the table.
ON DUPLICATE KEY UPDATE
clause (new in MySQL 4.1.0), and
a row is inserted that would cause a duplicate value in a PRIMARY
or
UNIQUE
key, an UPDATE
of the old row is performed. For
example, the command:
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3) -> ON DUPLICATE KEY UPDATE c=c+1;in case of column
a
is declared as UNIQUE
and already
holds 1
once, would be identical to the
mysql> UPDATE table SET c=c+1 WHERE a=1;Note: that if column
b
is unique too, the
UPDATE
command would be written as
mysql> UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;and if
a=1 OR b=2
matches several rows, only one row
will be updated! In general, one should try to avoid using
ON DUPLICATE KEY
clause on tables with multiple UNIQUE
keys.
Since MySQL 4.1.1 one can use function VALUES(col_name)
to refer to the column value in the INSERT
part of the
INSERT ... UPDATE
command - that is the value that would be
inserted if there would be no duplicate key conflict. This function
especially useful in multiple-row inserts. Naturally VALUES()
function is only meaningful in INSERT ... UPDATE
command
and returns NULL
otherwise.
Example:
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6) -> ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);The command above is identical to
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3) -> ON DUPLICATE KEY UPDATE c=3; mysql> INSERT INTO table (a,b,c) VALUES (4,5,6) -> ON DUPLICATE KEY UPDATE c=9;When one uses
ON DUPLICATE KEY UPDATE
,
the DELAYED
option is ignored.
DONT_USE_DEFAULT_FIELDS
option, INSERT
statements generate an error unless you explicitly
specify values for all columns that require a non-NULL
value.
See section 2.3.2 Typical configure
Options.
AUTO_INCREMENT
column
with the mysql_insert_id
function.
See section 19.1.3.32 mysql_insert_id()
.
If you use INSERT ... SELECT
or an INSERT ... VALUES
statement with multiple value lists, you can use the C API function
mysql_info()
to get information about the query. The format of the
information string is shown here:
Records: 100 Duplicates: 0 Warnings: 0
Duplicates
indicates the number of rows that couldn't be inserted
because they would duplicate some existing unique index value.
Warnings
indicates the number of attempts to insert column values that
were problematic in some way. Warnings can occur under any of the following
conditions:
NULL
into a column that has been declared NOT NULL
.
The column is set to the default value appropriate for the column type.
This is 0
for numeric types, the empty string (''
) for
string types, and the ``zero'' value for date and time types.
'10.34 a'
. The trailing
garbage is stripped and the remaining numeric part is inserted. If the value
doesn't make sense as a number at all, the column is set to 0
.
CHAR
, VARCHAR
, TEXT
, or
BLOB
column that exceeds the column's maximum length. The value is
truncated to the column's maximum length.
INSERT ... SELECT
SyntaxINSERT [LOW_PRIORITY] [IGNORE] [INTO] tbl_name [(column list)] SELECT ...
With INSERT ... SELECT
statement you can quickly insert many rows
into a table from one or many tables.
INSERT INTO tblTemp2 (fldID) SELECT tblTemp1.fldOrder_ID FROM tblTemp1 WHERE tblTemp1.fldOrder_ID > 100;
The following conditions hold for an INSERT ... SELECT
statement:
INSERT ... SELECT
implicitly operates in
IGNORE
mode. As of MySQL 4.0.1, you should specify IGNORE
explicitly to ignore records that would cause duplicate-key violations.
DELAYED
with INSERT ... SELECT
.
INSERT
statement cannot appear in the
FROM
clause of the SELECT
part of the query.
This limitation is lifted in 4.0.14.
AUTO_INCREMENT
columns work as usual.
mysql_info()
to get information about
the query. See section 13.1.4 INSERT
Syntax.
INSERT ... SELECT
.
You can use REPLACE
instead of INSERT
to overwrite old rows.
REPLACE
is the counterpart to INSERT IGNORE
in the treatment
of new rows that contain unique key values that duplicate old rows:
The new rows are used to replace the old rows rather than being discarded.
INSERT DELAYED
SyntaxINSERT DELAYED ...
The DELAYED
option for the INSERT
statement is a
MySQL-specific option that is very useful if you have clients
that can't wait for the INSERT
to complete. This is a common
problem when you use MySQL for logging and you also
periodically run SELECT
and UPDATE
statements that take a
long time to complete. DELAYED
was introduced in MySQL
Version 3.22.15. It is a MySQL extension to SQL-92.
INSERT DELAYED
only works with ISAM
and MyISAM
tables. Note that as MyISAM
tables support concurrent
SELECT
and INSERT
, if there is no free blocks in the
middle of the datafile, you very seldom need to use INSERT
DELAYED
with MyISAM
. See section 14.1 MyISAM
Tables.
INSERT DELAYED
should be used only for INSERT
statements that
specify value lists. This is enforced as of MySQL 4.0.18; the server ignores
DELAYED
for INSERT DELAYED ... SELECT
statements.
When you use INSERT DELAYED
, the client will get an OK at once
and the row will be inserted when the table is not in use by any other thread.
Another major benefit of using INSERT DELAYED
is that inserts
from many clients are bundled together and written in one block. This is much
faster than doing many separate inserts.
Note that currently the queued rows are only stored in memory until they are
inserted into the table. This means that if you kill mysqld
the hard way (kill -9
) or if mysqld
dies unexpectedly, any
queued rows that weren't written to disk are lost!
The following describes in detail what happens when you use the
DELAYED
option to INSERT
or REPLACE
. In this
description, the ``thread'' is the thread that received an INSERT
DELAYED
command and ``handler'' is the thread that handles all
INSERT DELAYED
statements for a particular table.
DELAYED
statement for a table, a handler
thread is created to process all DELAYED
statements for the table, if
no such handler already exists.
DELAYED
lock already; if not, it tells the handler thread to do so. The
DELAYED
lock can be obtained even if other threads have a READ
or WRITE
lock on the table. However, the handler will wait for all
ALTER TABLE
locks or FLUSH TABLES
to ensure that the table
structure is up to date.
INSERT
statement, but instead of writing
the row to the table, it puts a copy of the final row into a queue that
is managed by the handler thread. Any syntax errors are noticed by the
thread and reported to the client program.
AUTO_INCREMENT
value for the resulting row; it can't obtain them from the server, because
the INSERT
returns before the insert operation has been completed. If
you use the C API, the mysql_info()
function doesn't return anything
meaningful, for the same reason.
delayed_insert_limit
rows are written, the handler checks
whether any SELECT
statements are still pending. If so, it
allows these to execute before continuing.
INSERT DELAYED
commands are received within
delayed_insert_timeout
seconds, the handler terminates.
delayed_queue_size
rows are pending already in a
specific handler queue, the thread requesting INSERT DELAYED
waits until there is room in the queue. This is done to ensure that
the mysqld
server doesn't use all memory for the delayed memory
queue.
delayed_insert
in the Command
column. It will
be killed if you execute a FLUSH TABLES
command or kill it with
KILL thread_id
. However, it will first store all queued rows into the
table before exiting. During this time it will not accept any new
INSERT
commands from another thread. If you execute an INSERT
DELAYED
command after this, a new handler thread will be created.
Note that the above means that INSERT DELAYED
commands have higher
priority than normal INSERT
commands if there is an INSERT
DELAYED
handler already running! Other update commands will have to wait
until the INSERT DELAYED
queue is empty, someone kills the handler
thread (with KILL thread_id
), or someone executes FLUSH TABLES
.
INSERT
DELAYED
commands:
Variable | Meaning |
Delayed_insert_threads | Number of handler threads |
Delayed_writes | Number of rows written with INSERT DELAYED
|
Not_flushed_delayed_rows | Number of rows waiting to be written |
SHOW STATUS
statement or
by executing a mysqladmin extended-status
command.
Note that INSERT DELAYED
is slower than a normal INSERT if the
table is not in use. There is also the additional overhead for the
server to handle a separate thread for each table on which you use
INSERT DELAYED
. This means that you should only use INSERT
DELAYED
when you are really sure you need it!
LOAD DATA INFILE
SyntaxLOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name.txt' [REPLACE | IGNORE] INTO TABLE tbl_name [FIELDS [TERMINATED BY '\t'] [[OPTIONALLY] ENCLOSED BY ''] [ESCAPED BY '\\' ] ] [LINES [STARTING BY ''] [TERMINATED BY '\n'] ] [IGNORE number LINES] [(col_name,...)]
The LOAD DATA INFILE
statement reads rows from a text file into a
table at a very high speed. If the LOCAL
keyword is specified, it is
interpreted with respect to the client end of the connection. When
LOCAL
is specified, the file is read by the client program on the client
host and sent to the server. If LOCAL
is not specified, the
file must be located on the server host and is read directly by the server.
(LOCAL
is available in MySQL Version 3.22.6 or later.)
For security reasons, when reading text files located on the server, the
files must either reside in the database directory or be readable by all.
Also, to use LOAD DATA INFILE
on server files, you must have the
FILE
privilege on the server host.
See section 5.3.7 Privileges Provided by MySQL.
As of MySQL 3.23.49 and MySQL 4.0.2 (4.0.13 on Windows),
LOCAL
will work only if your server
and your client both have been enabled to allow it. For example, if
mysqld
was started with --local-infile=0
, LOCAL
will
not work.
See section 5.3.4 Security issues with LOAD DATA LOCAL
.
If you specify the keyword LOW_PRIORITY
, execution of the
LOAD DATA
statement is delayed until no other clients are reading
from the table.
If you specify the keyword CONCURRENT
with a MyISAM
table,
then other threads can retrieve data from the table while LOAD
DATA
is executing. Using this option will affect the
performance of LOAD DATA
a bit even if no other thread is using
the table at the same time.
Using LOCAL
will be a bit slower than letting the server access the
files directly, because the contents of the file must be sent over the
connection by the client
to the server. On the other hand, you do not need the
FILE
privilege to load local files.
If you are using MySQL before Version 3.23.24 you can't read from a
FIFO with LOAD DATA INFILE
. If you need to read from a FIFO (for
example the output from gunzip), use LOAD DATA LOCAL INFILE
instead.
You can also load datafiles by using the mysqlimport
utility; it
operates by sending a LOAD DATA INFILE
command to the server. The
--local
option causes mysqlimport
to read datafiles from the
client host. You can specify the --compress
option to get better
performance over slow networks if the client and server support the
compressed protocol.
When locating files on the server host, the server uses the following rules:
Note that these rules mean a file named as `./myfile.txt' is read from
the server's data directory, whereas the same file named as `myfile.txt' is
read from the database directory of the current database. For example,
the following LOAD DATA
statement reads the file `data.txt'
from the database directory for db1
because db1
is the current
database, even though the statement explicitly loads the file into a
table in the db2
database:
mysql> USE db1; mysql> LOAD DATA INFILE "data.txt" INTO TABLE db2.my_table;
The REPLACE
and IGNORE
keywords control handling of input
records that duplicate existing records on unique key values.
If you specify REPLACE
, input rows replace existing rows (in other
words rows that has the same value for a primary or unique index as an
existing row). See section 13.1.6 REPLACE
Syntax.
If you specify IGNORE
, input rows that duplicate an existing row
on a unique key value are skipped. If you don't specify either option,
the behavior depends on whether or not the LOCAL
keyword is specified.
Without LOCAL
, an error occurs when a duplicate key value is
found, and the rest of the text file is ignored. With LOCAL
,
the default behavior is the same as if IGNORE
is specified;
this is because the server has no way to stop transmission of the file
in the middle of the operation.
If you want to ignore foreign key constraints during load you can do
SET FOREIGN_KEY_CHECKS=0
before executing LOAD DATA
.
If you use LOAD DATA INFILE
on an empty MyISAM
table, all
non-unique indexes are created in a separate batch (like in
REPAIR
). This normally makes LOAD DATA INFILE
much faster
when you have many indexes. Normally this is very fast, but in some
extreme cases you can create the indexes even faster by turning them off
with ALTER TABLE .. DISABLE KEYS
and use ALTER TABLE .. ENABLE
KEYS
to recreate the indexes.
See section 5.5.2 Using myisamchk
for Table Maintenance and Crash Recovery.
LOAD DATA INFILE
is the complement of SELECT ... INTO OUTFILE
.
See section 13.1.7 SELECT
Syntax.
To write data from a table to a file, use SELECT ... INTO OUTFILE
.
To read the file back into a table, use LOAD DATA INFILE
.
The syntax of the FIELDS
and LINES
clauses is the same for
both commands. Both clauses are optional, but FIELDS
must precede LINES
if both are specified.
If you specify a FIELDS
clause,
each of its subclauses (TERMINATED BY
, [OPTIONALLY] ENCLOSED
BY
, and ESCAPED BY
) is also optional, except that you must
specify at least one of them.
If you don't specify a FIELDS
clause, the defaults are the
same as if you had written this:
FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
If you don't specify a LINES
clause, the default
is the same as if you had written this:
LINES TERMINATED BY '\n'
Note: If you have generated the text file on a Windows system
you may have to change the above to: LINES TERMINATED BY '\r\n'
as Windows uses two characters as a line terminator. Some programs, like
wordpad
, may use \r
as a line terminator.
If all the lines you want to read in has a common prefix that you want
to skip, you can use LINES STARTING BY prefix_string
for this.
In other words, the defaults cause LOAD DATA INFILE
to act as follows
when reading input:
LINES STARTING BY prefix
is used, read until prefix is found
and start reading at character after prefix. If line doesn't include prefix
it will be skipped.
Conversely, the defaults cause SELECT ... INTO OUTFILE
to act as
follows when writing output:
Note that to write FIELDS ESCAPED BY '\\'
, you must specify two
backslashes for the value to be read as a single backslash.
The IGNORE number LINES
option can be used to ignore lines at
the start of the file. For example, you can use IGNORE 1 LINES
to skip over an initial header line containing column names:
mysql> LOAD DATA INFILE "/tmp/file_name" INTO TABLE test IGNORE 1 LINES;
When you use SELECT ... INTO OUTFILE
in tandem with LOAD
DATA INFILE
to write data from a database into a file and then read
the file back into the database later, the field and line handling
options for both commands must match. Otherwise, LOAD DATA
INFILE
will not interpret the contents of the file properly. Suppose
you use SELECT ... INTO OUTFILE
to write a file with
fields delimited by commas:
mysql> SELECT * INTO OUTFILE 'data.txt' -> FIELDS TERMINATED BY ',' -> FROM ...;
To read the comma-delimited file back in, the correct statement would be:
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2 -> FIELDS TERMINATED BY ',';
If instead you tried to read in the file with the statement shown here, it
wouldn't work because it instructs LOAD DATA INFILE
to look for
tabs between fields:
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2 -> FIELDS TERMINATED BY '\t';
The likely result is that each input line would be interpreted as a single field.
LOAD DATA INFILE
can be used to read files obtained from
external sources, too. For example, a file in dBASE format will have
fields separated by commas and enclosed in double quotes. If lines in
the file are terminated by newlines, the command shown here
illustrates the field and line handling options you would use to load
the file:
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name -> FIELDS TERMINATED BY ',' ENCLOSED BY '"' -> LINES TERMINATED BY '\n';
Any of the field or line handling options may specify an empty string
(''
). If not empty, the FIELDS [OPTIONALLY] ENCLOSED BY
and FIELDS ESCAPED BY
values must be a single character. The
FIELDS TERMINATED BY
and LINES TERMINATED BY
values may
be more than one character. For example, to write lines that are
terminated by carriage return-linefeed pairs, or to read a file
containing such lines, specify a LINES TERMINATED BY '\r\n'
clause.
For example, to read a file of jokes, that are separated with a line
of %%
, into an SQL table you can do:
CREATE TABLE jokes (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, joke TEXT NOT NULL); LOAD DATA INFILE "/tmp/jokes.txt" INTO TABLE jokes FIELDS TERMINATED BY "" LINES TERMINATED BY "\n%%\n" (joke);
FIELDS [OPTIONALLY] ENCLOSED BY
controls quoting of fields. For
output (SELECT ... INTO OUTFILE
), if you omit the word
OPTIONALLY
, all fields are enclosed by the ENCLOSED BY
character. An example of such output (using a comma as the field
delimiter) is shown here:
"1","a string","100.20" "2","a string containing a , comma","102.20" "3","a string containing a \" quote","102.20" "4","a string containing a \", quote and comma","102.20"
If you specify OPTIONALLY
, the ENCLOSED BY
character is
used only to enclose CHAR
and VARCHAR
fields:
1,"a string",100.20 2,"a string containing a , comma",102.20 3,"a string containing a \" quote",102.20 4,"a string containing a \", quote and comma",102.20
Note that occurrences of the ENCLOSED BY
character within a
field value are escaped by prefixing them with the ESCAPED BY
character. Also note that if you specify an empty ESCAPED BY
value, it is possible to generate output that cannot be read properly by
LOAD DATA INFILE
. For example, the preceding output just shown would
appear as follows if the escape character is empty. Observe that the
second field in the fourth line contains a comma following the quote, which
(erroneously) appears to terminate the field:
1,"a string",100.20 2,"a string containing a , comma",102.20 3,"a string containing a " quote",102.20 4,"a string containing a ", quote and comma",102.20
For input, the ENCLOSED BY
character, if present, is stripped
from the ends of field values. (This is true whether OPTIONALLY
is specified; OPTIONALLY
has no effect on input interpretation.)
Occurrences of the ENCLOSED BY
character preceded by the
ESCAPED BY
character are interpreted as part of the current
field value.
If the field begins with the ENCLOSED BY
character, instances
of that character are recognized as terminating a field value only
if followed by the field or line TERMINATED BY
sequence.
To avoid ambiguity, occurrences of the ENCLOSED BY
character
within a field value can be doubled and will be interpreted as a
single instance of the character. For example, if ENCLOSED
BY '"'
is specified, quotes are handled as shown here:
"The ""BIG"" boss" -> The "BIG" boss The "BIG" boss -> The "BIG" boss The ""BIG"" boss -> The ""BIG"" boss
FIELDS ESCAPED BY
controls how to write or read special characters.
If the FIELDS ESCAPED BY
character is not empty, it is used to prefix
the following characters on output:
FIELDS ESCAPED BY
character
FIELDS [OPTIONALLY] ENCLOSED BY
character
FIELDS TERMINATED BY
and
LINES TERMINATED BY
values
0
(what is actually written following the escape character is
ASCII '0'
, not a zero-valued byte)
If the FIELDS ESCAPED BY
character is empty, no characters are escaped.
It is probably not a good idea to specify an empty escape character,
particularly if field values in your data contain any of the characters in
the list just given.
For input, if the FIELDS ESCAPED BY
character is not empty, occurrences
of that character are stripped and the following character is taken literally
as part of a field value. The exceptions are an escaped `0' or
`N' (for example, \0
or \N
if the escape character is
`\'). These sequences are interpreted as ASCII 0
(a zero-valued
byte) and NULL
. See below for the rules on NULL
handling.
For more information about `\'-escape syntax, see section 10.1 Literal Values.
In certain cases, field and line handling options interact:
LINES TERMINATED BY
is an empty string and FIELDS
TERMINATED BY
is non-empty, lines are also terminated with
FIELDS TERMINATED BY
.
FIELDS TERMINATED BY
and FIELDS ENCLOSED BY
values
are both empty (''
), a fixed-row (non-delimited) format is used.
With fixed-row format, no delimiters are used between fields (but you
can still have a line terminator). Instead, column values are written
and read using the ``display'' widths of the columns. For example, if a
column is declared as INT(7)
, values for the column are written
using 7-character fields. On input, values for the column are obtained
by reading 7 characters.
LINES TERMINATED BY
is still used to separate lines. If a line
doesn't contain all fields, the rest of the fields will be set to their
default values. If you don't have a line terminator, you should set this
to ''
. In this case the text file must contain all fields for
each row.
Fixed-row format also affects handling of NULL
values; see below.
Note that fixed-size format will not work if you are using a multi-byte
character set.
Handling of NULL
values varies, depending on the FIELDS
and
LINES
options you use:
FIELDS
and LINES
values,
NULL
is written as \N
for output and \N
is read
as NULL
for input (assuming the ESCAPED BY
character
is `\').
FIELDS ENCLOSED BY
is not empty, a field containing the literal
word NULL
as its value is read as a NULL
value (this differs
from the word NULL
enclosed within FIELDS ENCLOSED BY
characters, which is read as the string 'NULL'
).
FIELDS ESCAPED BY
is empty, NULL
is written as the word
NULL
.
FIELDS TERMINATED BY
and
FIELDS ENCLOSED BY
are both empty), NULL
is written as an empty
string. Note that this causes both NULL
values and empty strings in
the table to be indistinguishable when written to the file because they are
both written as empty strings. If you need to be able to tell the two apart
when reading the file back in, you should not use fixed-row format.
Some cases are not supported by LOAD DATA INFILE
:
FIELDS TERMINATED BY
and FIELDS ENCLOSED
BY
both empty) and BLOB
or TEXT
columns.
LOAD DATA INFILE
won't be able to interpret the input properly.
For example, the following FIELDS
clause would cause problems:
FIELDS TERMINATED BY '"' ENCLOSED BY '"'
FIELDS ESCAPED BY
is empty, a field value that contains an occurrence
of FIELDS ENCLOSED BY
or LINES TERMINATED BY
followed by the FIELDS TERMINATED BY
value will cause LOAD
DATA INFILE
to stop reading a field or line too early.
This happens because LOAD DATA INFILE
cannot properly determine
where the field or line value ends.
The following example loads all columns of the persondata
table:
mysql> LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata;
No field list is specified, so LOAD DATA INFILE
expects input rows
to contain a field for each table column. The default FIELDS
and
LINES
values are used.
If you wish to load only some of a table's columns, specify a field list:
mysql> LOAD DATA INFILE 'persondata.txt' -> INTO TABLE persondata (col1,col2,...);
You must also specify a field list if the order of the fields in the input file differs from the order of the columns in the table. Otherwise, MySQL cannot tell how to match up input fields with table columns.
If a row has too few fields, the columns for which no input field is present
are set to default values. Default value assignment is described in
section 13.2.5 CREATE TABLE
Syntax.
An empty field value is interpreted differently than if the field value is missing:
0
.
Note that these are the same values that result if you assign an empty
string explicitly to a string, numeric, or date or time type explicitly
in an INSERT
or UPDATE
statement.
TIMESTAMP
columns are only set to the current date and time if there
is a NULL
value for the column (that is, \N
), or (for the
first TIMESTAMP
column only) if the TIMESTAMP
column is
omitted from the field list when a field list is specified.
If an input row has too many fields, the extra fields are ignored and
the number of warnings is incremented. Note that before MySQL 4.1.1 the
warnings is just a number to indicate that something went wrong.
In MySQL 4.1.1 you can do SHOW WARNINGS
to get more information for
what went wrong.
LOAD DATA INFILE
regards all input as strings, so you can't use
numeric values for ENUM
or SET
columns the way you can with
INSERT
statements. All ENUM
and SET
values must be
specified as strings!
If you are using the C API, you can get information about the query by
calling the API function mysql_info()
when the LOAD DATA INFILE
query finishes. The format of the information string is shown here:
Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
Warnings occur under the same circumstances as when values are inserted
via the INSERT
statement (see section 13.1.4 INSERT
Syntax), except
that LOAD DATA INFILE
also generates warnings when there are too few
or too many fields in the input row. The warnings are not stored anywhere;
the number of warnings can only be used as an indication if everything went
well.
If you get warnings and want to know exactly why you got them, one way
to do this is to use SELECT ... INTO OUTFILE
into another file
and compare this to your original input file.
If you need LOAD DATA
to read from a pipe, you can use the
following trick:
mkfifo /mysql/db/x/x chmod 666 /mysql/db/x/x cat < /dev/tcp/10.1.1.12/4711 > /nt/mysql/db/x/x mysql -e "LOAD DATA INFILE 'x' INTO TABLE x" x
If you are using a version of MySQL older than 3.23.25
you can only do the above with LOAD DATA LOCAL INFILE
.
In MySQL 4.1.1 you can use SHOW WARNINGS
to get a list of the first
max_error_count
warnings. See section 13.5.3.9 SHOW WARNINGS | ERRORS
.
For more information about the efficiency of INSERT
versus
LOAD DATA INFILE
and speeding up LOAD DATA INFILE
,
See section 7.2.11 Speed of INSERT
Queries.
REPLACE
SyntaxREPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [(col_name,...)] VALUES (expression,...),(...),... or REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [(col_name,...)] SELECT ... or REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name SET col_name=expression, col_name=expression,...
REPLACE
works exactly like INSERT
, except that if an old
record in the table has the same value as a new record on a UNIQUE
index or PRIMARY KEY
, the old record is deleted before the new
record is inserted.
See section 13.1.4 INSERT
Syntax.
In other words, you can't access the values of the old row from a
REPLACE
statement. In some old MySQL versions it appeared that
you could do this, but that was a bug that has been corrected.
To be able to use REPLACE
you must have INSERT
and
DELETE
privileges for the table.
When you use a REPLACE
command, mysql_affected_rows()
will return 2 if the new row replaced an old row. This is because
one row was inserted after the duplicate was deleted.
This fact makes it easy to determine whether REPLACE
added
or replaced a row: check whether the affected-rows value is 1 (added)
or 2 (replaced).
Note that unless the table has a UNIQUE
index or PRIMARY KEY
,
using a REPLACE
command makes no sense. It becomes equivalent to
INSERT
, because there is no index to be used to determine whether a new
row duplicates another.
Here follows the used algorithm in more detail:
(This is also used with LOAD DATA ... REPLACE
.
- Insert the row into the table - While duplicate key error for primary or unique key - Revert changed keys - Read conflicting row from the table through the duplicate key value - Delete conflicting row - Try again to insert the original primary key and unique keys in the tree
SELECT
SyntaxSELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] [HIGH_PRIORITY] [DISTINCT | DISTINCTROW | ALL] select_expression,... [INTO {OUTFILE | DUMPFILE} 'file_name' export_options] [FROM table_references [WHERE where_definition] [GROUP BY {unsigned_integer | col_name | formula} [ASC | DESC], ... [WITH ROLLUP]] [HAVING where_definition] [ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] ,...] [LIMIT [offset,] row_count | row_count OFFSET offset] [PROCEDURE procedure_name(argument_list)] [FOR UPDATE | LOCK IN SHARE MODE]]
SELECT
is used to retrieve rows selected from one or more tables.
Each select_expression
indicates a column you want to retrieve.
SELECT
may also be used to retrieve rows computed without reference to
any table.
For example:
mysql> SELECT 1 + 1; -> 2
All clauses used must be given in exactly the order shown in the syntax
description. For example,
a HAVING
clause must come after any GROUP BY
clause and before
any ORDER BY
clause.
SELECT
expression may be given an alias using AS alias_name
.
The alias is used as the expression's column name and can be used with
ORDER BY
or HAVING
clauses. For example:
mysql> SELECT CONCAT(last_name,', ',first_name) AS full_name FROM mytable ORDER BY full_name;The
AS
keyword is optional when aliasing a SELECT
expression.
The preceding example could have been written like this:
mysql> SELECT CONCAT(last_name,', ',first_name) full_name FROM mytable ORDER BY full_name;Because the
AS
is optional, a subtle problem can occur
if you forget the comma between two SELECT
expressions: MySQL will
interpret the second as an alias name. For example, in the following
statement, columnb
is treated as an alias name:
mysql> SELECT columna columnb FROM mytable;
WHERE
clause,
because the column value may not yet be determined when the
WHERE
clause is executed.
See section A.5.4 Problems with alias
.
FROM table_references
clause indicates the tables from which to
retrieve rows. If you name more than one table, you are performing a
join. For information on join syntax, see section 13.1.7.1 JOIN
Syntax.
For each table specified, you may optionally specify an alias.
table_name [[AS] alias] [[USE INDEX (key_list)] | [IGNORE INDEX (key_list)] | [FORCE INDEX (key_list)]]As of MySQL Version 3.23.12, you can give hints about which index MySQL should use when retrieving information from a table. This is useful if
EXPLAIN
shows that MySQL is
using the wrong index from the list of possible indexes. By specifying
USE INDEX (key_list)
, you can tell MySQL to use only one of the
possible indexes to find rows in the table. The alternative syntax
IGNORE INDEX (key_list)
can be used to tell MySQL to not use some
particular index.
In MySQL 4.0.9 you can also use FORCE INDEX
. This acts likes
USE INDEX (key_list)
but with the addition that a table scan
is assumed to be VERY expensive. In other words a table scan will
only be used if there is no way to use one of the given index to
find rows in the table.
USE/IGNORE/FORCE KEY
are synonyms for USE/IGNORE/FORCE INDEX
.
Note: USE/IGNORE/FORCE INDEX
only affects which indexes are
used when MySQL decides how to find rows in the table and how to do the
join. It doesn't affect whether an index will be used when resolving an
ORDER BY
or GROUP BY
.
In MySQL 4.0.14, you can use SET MAX_SEEKS_FOR_KEY=value
as an
alternative way to force MySQL to prefer key scans instead of table scans.
tbl_name
(within the current database),
or as dbname.tbl_name
to explicitly specify a database.
You can refer to a column as col_name
, tbl_name.col_name
, or
db_name.tbl_name.col_name
. You need not specify a tbl_name
or
db_name.tbl_name
prefix for a column reference in a SELECT
statement unless the reference would be ambiguous. See section 10.2 Database, Table, Index, Column, and Alias Names,
for examples of ambiguity that require the more explicit column reference
forms.
DUAL
as a dummy
table name, in situations where no tables are referenced. This is purely
compatibility feature, some other servers require this syntax.
mysql> SELECT 1 + 1 FROM DUAL; -> 2
tbl_name [AS] alias_name
:
mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2 -> WHERE t1.name = t2.name; mysql> SELECT t1.name, t2.salary FROM employee t1, info t2 -> WHERE t1.name = t2.name;
ORDER BY
and
GROUP BY
clauses using column names, column aliases, or column
positions. Column positions begin with 1:
mysql> SELECT college, region, seed FROM tournament -> ORDER BY region, seed; mysql> SELECT college, region AS r, seed AS s FROM tournament -> ORDER BY r, s; mysql> SELECT college, region, seed FROM tournament -> ORDER BY 2, 3;To sort in reverse order, add the
DESC
(descending) keyword to the
name of the column in the ORDER BY
clause that you are sorting by.
The default is ascending order; this may be specified explicitly using
the ASC
keyword.
WHERE
clause, you can use any of the functions that
MySQL supports, except for aggregate (summary) functions.
See section 12 Functions and Operators.
HAVING
clause can refer to any column or alias named in the
select_expression
. It is applied nearly last, just before items are
sent to the client, with no optimization. (LIMIT
is applied after
HAVING
.) Don't use HAVING
for items that
should be in the WHERE
clause. For example, do not write this:
mysql> SELECT col_name FROM tbl_name HAVING col_name > 0;Write this instead:
mysql> SELECT col_name FROM tbl_name WHERE col_name > 0;In MySQL Version 3.22.5 or later, you can also write queries like this:
mysql> SELECT user,MAX(salary) FROM users -> GROUP BY user HAVING MAX(salary)>10;In older MySQL versions, you can write this instead:
mysql> SELECT user,MAX(salary) AS sum FROM users -> group by user HAVING sum>10;
DISTINCT
, DISTINCTROW
and ALL
specify
whether duplicate rows should be returned. The default is (ALL
),
all matching rows are returned. DISTINCT
and DISTINCTROW
are synonyms and specify that duplicate rows in the result set should
be removed.
STRAIGHT_JOIN
, HIGH_PRIORITY
, and options beginning with
SQL_
are MySQL extensions to SQL-99.
STRAIGHT_JOIN
forces the optimizer to join the tables in the order in
which they are listed in the FROM
clause. You can use this to speed up
a query if the optimizer joins the tables in non-optimal order.
See section 7.2.1 EXPLAIN
Syntax (Get Information About a SELECT
).
HIGH_PRIORITY
will give the SELECT
higher priority than
a statement that updates a table. You should only use this for queries
that are very fast and must be done at once. A SELECT HIGH_PRIORITY
query will run if the table is locked for read even if there is an update
statement that is waiting for the table to be free.
SQL_BIG_RESULT
can be used with GROUP BY
or DISTINCT
to tell the optimizer that the result set will have many rows. In this case,
MySQL will directly use disk-based temporary tables if needed.
MySQL will also, in this case, prefer sorting to doing a
temporary table with a key on the GROUP BY
elements.
SQL_BUFFER_RESULT
forces the result to be put into a temporary
table. This helps MySQL free the table locks early and helps
in cases where it takes a long time to send the result set to the client.
SQL_SMALL_RESULT
, a MySQL-specific option, can be used
with GROUP BY
or DISTINCT
to tell the optimizer that the
result set will be small. In this case, MySQL uses fast
temporary tables to store the resulting table instead of using sorting. In
MySQL Version 3.23 this shouldn't normally be needed.
SQL_CALC_FOUND_ROWS
(version 4.0.0 and up) tells MySQL to calculate
how many rows there would be in the result set, disregarding any
LIMIT
clause.
The number of rows can then be retrieved with SELECT FOUND_ROWS()
.
See section 12.6.4 Miscellaneous Functions.
Please note that in versions prior to 4.1.0 this does not work with
LIMIT 0
, which is optimized to return instantly (resulting in a
row count of 0). See section 7.2.10 How MySQL Optimizes LIMIT
.
SQL_CACHE
tells MySQL to store the query result in the query cache
if you are using QUERY_CACHE_TYPE=2
(DEMAND
).
See section 13.8 MySQL Query Cache. For a query that uses UNION
or subqueries, this
option takes effect to be used in any SELECT
of the query.
SQL_NO_CACHE
tells MySQL not to store the query result
in the query cache. See section 13.8 MySQL Query Cache.
For a query that uses UNION
or subqueries, this
option takes effect to be used in any SELECT
of the query.
GROUP BY
, the output rows will be sorted according to the
GROUP BY
as if you had an ORDER BY
over all the fields
in the GROUP BY
. MySQL has extended the GROUP BY
clause so that
you can also specify ASC
and DESC
after columns named in the
clause:
SELECT a,COUNT(b) FROM test_table GROUP BY a DESC
GROUP BY
to allow you to
select fields that are not mentioned in the GROUP BY
clause.
If you are not getting the results you expect from your query, please
read the GROUP BY
description.
See section 12.7 Functions and Modifiers for Use with GROUP BY
Clauses.
GROUP BY
allows a WITH ROLLUP
modifier.
See section 12.7.2 GROUP BY
Modifiers.
LIMIT
clause can be used to constrain the number of rows returned
by the SELECT
statement. LIMIT
takes one or two numeric
arguments, which must be integer constants.
With one argument, the value specifies the number of rows to return from the
beginning of the result set.
With two arguments, the first specifies the offset of the first row to
return, the second specifies the maximum number of rows to return.
The offset of the initial row is 0 (not 1):
To be compatible with PostgreSQL MySQL also supports the syntax:
LIMIT row_count OFFSET offset
.
mysql> SELECT * FROM table LIMIT 5,10; # Retrieve rows 6-15To retrieve all rows from a certain offset up to the end of the result set, you can use some big number for the second parameter:
mysql> SELECT * FROM table LIMIT 95,18446744073709551615; # Retrieve rows 96-last.If one argument is given, it indicates the maximum number of rows to return:
mysql> SELECT * FROM table LIMIT 5; # Retrieve first 5 rowsIn other words,
LIMIT n
is equivalent to LIMIT 0,n
.
SELECT ... INTO OUTFILE 'file_name'
form of SELECT
writes
the selected rows to a file. The file is created on the server host and
cannot already exist (among other things, this prevents database tables and
files such as `/etc/passwd' from being destroyed). You must have the
FILE
privilege on the server host to use this form of SELECT
.
The SELECT ... INTO OUTFILE
statement is intended primarily to let you very
quickly dump a table on the server machine. If you want to create the
resulting file on some other host than the server host, you can't use
SELECT ... INTO OUTFILE
. In this case you should instead use some
client program like mysqldump --tab
or mysql -e "SELECT
..." > outfile
to generate the file.
SELECT ... INTO OUTFILE
is the complement of LOAD DATA
INFILE
; the syntax for the export_options
part of the statement
consists of the same FIELDS
and LINES
clauses that are used
with the LOAD DATA INFILE
statement.
See section 13.1.5 LOAD DATA INFILE
Syntax.
In the resulting text file, only the following characters are escaped by
the ESCAPED BY
character:
ESCAPED BY
character
FIELDS TERMINATED BY
LINES TERMINATED BY
ASCII 0
is converted to ESCAPED BY
followed by 0
(ASCII 48
).
The reason for the above is that you must escape any FIELDS
TERMINATED BY
, ESCAPED BY
, or LINES TERMINATED BY
characters to reliably be able to read the file back. ASCII 0
is
escaped to make it easier to view with some pagers.
As the resulting file doesn't have to conform to the SQL syntax, nothing
else need be escaped.
Here follows an example of getting a file in the format used by many
old programs.
SELECT a,b,a+b INTO OUTFILE "/tmp/result.text" FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY "\n" FROM test_table;
INTO DUMPFILE
instead of INTO OUTFILE
, MySQL
will only write one row into the file, without any column or line
terminations and without performing any escape processing. This is useful if you want to
store a BLOB
value in a file.
INTO OUTFILE
and INTO
DUMPFILE
will be writeable by all users on the server host! The reason is that the
MySQL server can't create a file that is owned by anyone else
than the user it's running as (you should never run mysqld
as
root
).
The file thus must be world-writeable so that you can manipulate its contents.
PROCEDURE
clause names a procedure that should process the data
in the result set. For an example, see section 21.3.1 Procedure Analyse.
FOR UPDATE
on a storage engine with page or row locks,
the examined rows are write locked until the end of the current
transaction.
JOIN
Syntax
MySQL supports the following JOIN
syntaxes for use in
SELECT
statements:
table_reference, table_reference table_reference [INNER | CROSS] JOIN table_reference [join_condition] table_reference STRAIGHT_JOIN table_reference table_reference LEFT [OUTER] JOIN table_reference [join_condition] table_reference NATURAL [LEFT [OUTER]] JOIN table_reference { OJ table_reference LEFT OUTER JOIN table_reference ON conditional_expr } table_reference RIGHT [OUTER] JOIN table_reference [join_condition] table_reference NATURAL [RIGHT [OUTER]] JOIN table_reference
Where table_reference
is defined as:
table_name [[AS] alias] [[USE INDEX (key_list)] | [IGNORE INDEX (key_list)] | [FORCE INDEX (key_list)]]
and join_condition
is defined as:
ON conditional_expr | USING (column_list)
You should generally not have any conditions in the ON
part that are
used to restrict which rows you want in the result set, but rather specify
these conditions in the WHERE
clause. There are exceptions to this rule.
Note that INNER JOIN
syntax allows a join_condition
only from
MySQL 3.23.17 on. The same is true for JOIN
and CROSS JOIN
only
as of MySQL 4.0.11.
The last LEFT OUTER JOIN
syntax shown in the preceding list exists only for
compatibility with ODBC:
tbl_name AS alias_name
or
tbl_name alias_name
:
mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2 -> WHERE t1.name = t2.name;
ON
conditional is any conditional of the form that may be used in
a WHERE
clause.
ON
or
USING
part in a LEFT JOIN
, a row with all columns set to
NULL
is used for the right table. You can use this fact to find
records in a table that have no counterpart in another table:
mysql> SELECT table1.* FROM table1 -> LEFT JOIN table2 ON table1.id=table2.id -> WHERE table2.id IS NULL;This example finds all rows in
table1
with an id
value that is
not present in table2
(that is, all rows in table1
with no
corresponding row in table2
). This assumes that table2.id
is
declared NOT NULL
. See section 7.2.8 How MySQL Optimizes LEFT JOIN
and RIGHT JOIN
.
USING
(column_list)
clause names a list of columns that must
exist in both tables. The following two clauses are semantically identical:
a LEFT JOIN b USING (c1,c2,c3) a LEFT JOIN b ON a.c1=b.c1 AND a.c2=b.c2 AND a.c3=b.c3
NATURAL [LEFT] JOIN
of two tables is defined to be
semantically equivalent to an INNER JOIN
or a LEFT JOIN
with a USING
clause that names all columns that exist in both
tables.
INNER JOIN
and ,
(comma) are semantically equivalent in
the absence of a join condition: both will produce a Cartesian product
between the specified tables (that is, each and every row in the first table
will be joined onto all rows in the second table).
RIGHT JOIN
works analogously to LEFT JOIN
. To keep code
portable across databases, it's recommended to use LEFT JOIN
instead of RIGHT JOIN
.
STRAIGHT_JOIN
is identical to JOIN
, except that the left table
is always read before the right table. This can be used for those (few)
cases where the join optimizer puts the tables in the wrong order.
EXPLAIN
shows that MySQL is
using the wrong index from the list of possible indexes. By specifying
USE INDEX (key_list)
, you can tell MySQL to use only one of the
possible indexes to find rows in the table. The alternative syntax
IGNORE INDEX (key_list)
can be used to tell MySQL to not use some
particular index.
In MySQL 4.0.9 you can also use FORCE INDEX
. This acts likes
USE INDEX (key_list)
but with the addition that a table scan
is assumed to be VERY expensive. In other words a table scan will
only be used if there is no way to use one of the given index to
find rows in the table.
USE/IGNORE KEY
are synonyms for USE/IGNORE INDEX
.
Note: USE/IGNORE/FORCE INDEX
only affects which indexes are
used when MySQL decides how to find rows in the table and how to do the
join. It doesn't affect whether an index will be used when resolving an
ORDER BY
or GROUP BY
.
Some examples:
mysql> SELECT * FROM table1,table2 WHERE table1.id=table2.id; mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id; mysql> SELECT * FROM table1 LEFT JOIN table2 USING (id); mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id -> LEFT JOIN table3 ON table2.id=table3.id; mysql> SELECT * FROM table1 USE INDEX (key1,key2) -> WHERE key1=1 AND key2=2 AND key3=3; mysql> SELECT * FROM table1 IGNORE INDEX (key3) -> WHERE key1=1 AND key2=2 AND key3=3;
See section 7.2.8 How MySQL Optimizes LEFT JOIN
and RIGHT JOIN
.
UNION
SyntaxSELECT ... UNION [ALL | DISTINCT] SELECT ... [UNION [ALL | DISTINCT] SELECT ...]
UNION
is implemented in MySQL 4.0.0.
UNION
is used to combine the result from many SELECT
statements into one result set.
The columns listed in the select_expression
portion of the SELECT
should have the same type. The column names used in the first
SELECT
query will be used as the column names for the results
returned.
The SELECT
commands are normal select commands, but with the following
restrictions:
SELECT
command can have INTO OUTFILE
.
If you don't use the keyword ALL
for the UNION
, all
returned rows will be unique, as if you had done a DISTINCT
for
the total result set. If you specify ALL
, then you will get all
matching rows from all the used SELECT
statements.
The DISTINCT
keyword is an optional word (introduced in MySQL 4.0.17)
that does nothing. But it is required by the SQL standard.
If you want to use an ORDER BY
for the total UNION
result,
you should use parentheses:
(SELECT a FROM table_name WHERE a=10 AND B=1 ORDER BY a LIMIT 10) UNION (SELECT a FROM table_name WHERE a=11 AND B=2 ORDER BY a LIMIT 10) ORDER BY a;
Note: You cannot mix UNION ALL
and UNION
DISTINCT
in the same query yet. If you use ALL
for one
UNION
then it is used for all of them.
The types and lengths of the columns in the result set of a UNION
take into acccount the values retrieved by all the SELECT
statements.
Before MySQL 4.1.1, a limitation of UNION
is that only the values from
the first SELECT
were used to determine result types and lengths.
This could result in value truncation if, for example, the second
SELECT
retrieved longer values than the first SELECT
:
mysql> SELECT REPEAT('a',1) UNION SELECT REPEAT('b',10); +---------------+ | REPEAT('a',1) | +---------------+ | a | | b | +---------------+
That limitation has been removed as of MySQL 4.1.1:
mysql> SELECT REPEAT('a',1) UNION SELECT REPEAT('b',10); +---------------+ | REPEAT('a',1) | +---------------+ | a | | bbbbbbbbbb | +---------------+
A subquery is a SELECT
statement inside another statement.
For example:
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
In the above example, SELECT * FROM t1 ...
is the outer query
(or outer statement), and (SELECT column1 FROM t2)
is the
subquery.
We say that the subquery is nested in the outer query, and in fact
it's possible to nest subqueries within other subqueries, to a great depth.
A subquery must always be inside parentheses.
Starting with version 4.1, MySQL supports all subquery forms and operations which the SQL standard requires, as well as a few features which are MySQL-specific. The main advantages of subqueries are:
SQL
``Structured Query Language''.
With earlier MySQL versions it was necessary to work around or avoid subqueries, but people starting to write code now will find that subqueries are a very useful part of the toolkit.
Here is an example statement which shows the major points about subquery syntax as specified by the SQL standard and supported in MySQL.
DELETE FROM t1 WHERE s11 > ANY (SELECT COUNT(*) /* no hint */ FROM t2 WHERE NOT EXISTS (SELECT * FROM t3 WHERE ROW(5*t2.s1,77)= (SELECT 50,11*s1 FROM t4 UNION SELECT 50,77 FROM (SELECT * FROM t5) AS t5)));
For MySQL versions prior to 4.1, most subqueries can be successfully rewritten using joins and and other methods. See section 13.1.8.11 Rewriting Subqueries for Earlier MySQL Versions.
In its simplest form (the scalar subquery as opposed to the
row or table subqueries which will be discussed later),
a subquery is a simple operand. Thus you can use it wherever a column value
or literal is legal, and you can expect it to have those characteristics
that all operands have: a data type, a length, an indication whether it can
be NULL
, and so on.
For example:
CREATE TABLE t1 (s1 INT, s2 CHAR(5) NOT NULL); SELECT (SELECT s2 FROM t1);
The subquery in the above SELECT
has a data type of CHAR
,
a length of 5, a character set and collation equal to the defaults in
effect at CREATE TABLE
time, and an indication that the value in
the column can be NULL
. In fact almost all subqueries can be
NULL
, because if the table is empty -- as in the example -- then
the value of the subquery will be NULL
.
There are few restrictions.
SELECT
, INSERT
, UPDATE
, DELETE
,
SET
, or DO
.
SELECT
can contain:
DISTINCT
, GROUP BY
, ORDER BY
, LIMIT
,
joins, hints, UNION
constructs, comments, functions, and so on.
So, when you see examples in the following sections that contain the rather
Spartan construct (SELECT column1 FROM t1)
, imagine that your own
code will contain much more diverse and complex constructions.
For example, suppose we make two tables:
CREATE TABLE t1 (s1 INT); INSERT INTO t1 VALUES (1); CREATE TABLE t2 (s1 INT); INSERT INTO t2 VALUES (2);
Then perform a SELECT
:
SELECT (SELECT s1 FROM t2) FROM t1;
The result will be 2
because there is a row in t2
, with a
column s1
, with a value of 2.
The subquery may be part of an expression. If it is an operand for a function, don't forget the parentheses. For example:
SELECT UPPER((SELECT s1 FROM t1)) FROM t2;
The most common use of a subquery is in the form:
<non-subquery operand> <comparison operator> (<subquery>)
Where <comparison operator> is one of:
= > < >= <= <>
For example:
... 'a' = (SELECT column1 FROM t1)
At one time the only legal place for a subquery was on the right side of a comparison, and you might still find some old DBMSs which insist on that.
Here is an example of a common-form subquery comparison which you can't do
with a join: find all the values in table t1
which are equal to a
maximum value in table t2
.
SELECT column1 FROM t1 WHERE column1 = (SELECT MAX(column2) FROM t2);
Here is another example, which again is impossible with a join because it
involves aggregating for one of the tables: find all rows in table
t1
which contain a value which occurs twice.
SELECT * FROM t1 WHERE 2 = (SELECT COUNT(column1) FROM t1);
ANY
, IN
, and SOME
Syntax:
<operand> <comparison operator> ANY (<subquery>) <operand> IN (<subquery>) <operand> <comparison operator> SOME (<subquery>)
The word ANY
, which must follow a comparison operator, means
``return TRUE
if the comparison is TRUE
for ANY
of the
rows that the subquery returns.''
For example,
SELECT s1 FROM t1 WHERE s1 > ANY (SELECT s1 FROM t2);
Suppose that there is a row in table t1
containing {10}.
The expression is TRUE
if table t2
contains {21,14,7} because
there is a value in t2
-- 7 -- which is less than 10.
The expression is FALSE
if table t2
contains {20,10},
or if table t2
is empty.
The expression is UNKNOWN
if table t2
contains
{NULL
,NULL
,NULL
}.
The word IN
is an alias for = ANY
. Thus these two statements
are the same:
SELECT s1 FROM t1 WHERE s1 = ANY (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 IN (SELECT s1 FROM t2);
The word SOME
is an alias for ANY
. Thus these two statements
are the same:
SELECT s1 FROM t1 WHERE s1 <> ANY (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 <> SOME (SELECT s1 FROM t2);
Use of the word SOME
is rare, but the above example shows why it
might be useful. The English phrase ``a is not equal to any b'' means, to
most people's ears, ``there is no b which is equal to a'' -- which isn't
what is meant by the SQL syntax. By using <> SOME
instead, you
ensure that everyone understands the true meaning of the query.
ALL
Syntax:
<operand> <comparison operator> ALL (<subquery>)
The word ALL
, which must follow a comparison operator, means
``return TRUE
if the comparison is TRUE
for ALL
of
the rows that the subquery returns''.
For example,
SELECT s1 FROM t1 WHERE s1 > ALL (SELECT s1 FROM t2);
Suppose that there is a row in table t1
containing {10}.
The expression is TRUE
if table t2
contains {-5,0,+5}
because all three values in t2
are less than 10.
The expression is FALSE
if table t2
contains
{12,6,NULL,-100} because there is a single value in table t2
-- 12
-- which is greater than 10.
The expression is UNKNOWN
if table t2
contains {0,NULL,1}.
Finally, if table t2
is empty, the result is TRUE
.
You might think the result should be UNKNOWN
, but
sorry, it's TRUE
. So, rather oddly,
SELECT * FROM t1 WHERE 1 > ALL (SELECT s1 FROM t2);
is TRUE
when table t2
is empty, but
SELECT * FROM t1 WHERE 1 > (SELECT s1 FROM t2);
is UNKNOWN
when table t2
is empty. In addition,
SELECT * FROM t1 WHERE 1 > ALL (SELECT MAX(s1) FROM t2);
is UNKNOWN
when table t2
is empty.
In general, tables with NULLs and empty tables are
edge cases -- when writing subquery code, always consider whether
you have taken those two possibilities into account.
A correlated subquery is a subquery which contains a reference to a column which is also in the outer query. For example:
SELECT * FROM t1 WHERE column1 = ANY (SELECT column1 FROM t2 WHERE t2.column2 = t1.column2);
Notice, in the example, that the subquery contains a reference to a column
of t1
, even though the subquery's FROM
clause doesn't mention
a table t1
. So MySQL looks outside the subquery, and finds t1 in the
outer query.
Suppose that table t1
contains a row where column1 = 5
and
column2 = 6
; meanwhile table t2
contains a row where
column1 = 5
and column2 = 7
. The simple expression
... WHERE column1 = ANY (SELECT column1 FROM t2)
would be
TRUE
, but in this example the WHERE
clause within the
subquery is FALSE
(because 7 <> 5), so the subquery as a whole is
FALSE
.
Scoping rule: MySQL evaluates from inside to outside. For example:
SELECT column1 FROM t1 AS x WHERE x.column1 = (SELECT column1 FROM t2 AS x WHERE x.column1 = (SELECT column1 FROM t3 WHERE x.column2 = t3.column1));
In the above, x.column2
must be a column in table t2
because
SELECT column1 FROM t2 AS x ...
renames t2
. It is not a
column in table t1
because SELECT column1 FROM t1 ...
is an
outer query which is further out.
For subqueries in HAVING
or ORDER BY
clauses, MySQL also
looks for column names in the outer select list.
MySQL's unofficial recommendation is: avoid correlation because it makes your queries look more complex, and run more slowly.
EXISTS
and NOT EXISTS
If a subquery returns any values at all, then EXISTS <subquery>
is
TRUE
, and NOT EXISTS <subquery>
is FALSE
.
For example:
SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);
Traditionally an EXISTS
subquery starts with SELECT *
but it
could begin with SELECT 5
or SELECT column1
or anything at
all -- MySQL ignores the SELECT
list in such a subquery, so it
doesn't matter.
For the above example, if t2
contains any rows, even rows with
nothing but NULL
values, then the EXISTS
condition is
TRUE
. This is actually an unlikely example, since almost always a
[NOT] EXISTS
subquery will contain correlations.
Here are some more realistic examples.
Example: What kind of store is present in one or more cities?
SELECT DISTINCT store_type FROM Stores WHERE EXISTS (SELECT * FROM Cities_Stores WHERE Cities_Stores.store_type = Stores.store_type);
Example: What kind of store is present in no cities?
SELECT DISTINCT store_type FROM Stores WHERE NOT EXISTS (SELECT * FROM Cities_Stores WHERE Cities_Stores.store_type = Stores.store_type);
Example: What kind of store is present in all cities?
SELECT DISTINCT store_type FROM Stores S1 WHERE NOT EXISTS ( SELECT * FROM Cities WHERE NOT EXISTS ( SELECT * FROM Cities_Stores WHERE Cities_Stores.city = Cities.city AND Cities_Stores.store_type = Stores.store_type));
The last example is a double-nested NOT EXISTS
query -- it has a
NOT EXISTS
clause within a NOT EXISTS
clause. Formally, it
answers the question ``does a city exist with a store which is not in
Stores?''. But it's easier to say that a nested NOT EXISTS
answers
the question ``is x TRUE for all y?''.
The discussion to this point has been of column (or scalar) subqueries -- subqueries which return a single column value. A row subquery is a subquery variant that returns a single row value -- and may thus return more than one column value. Here are two examples:
SELECT * FROM t1 WHERE (1,2) = (SELECT column1, column2 FROM t2); SELECT * FROM t1 WHERE ROW(1,2) = (SELECT column1, column2 FROM t2);
The queries above are both TRUE
if table t2
has
a row where column1 = 1
and column2 = 2
.
The expression (1,2)
is sometimes called a row constructor
and is legal in other contexts too. For example
SELECT * FROM t1 WHERE (column1,column2) = (1,1);
is equivalent to
SELECT * FROM t1 WHERE column1 = 1 AND column2 = 1;
The normal use of row constructors, though, is for comparisons with subqueries that return two or more columns. For example, this query answers the request: ``find all rows in table t1 which are duplicated in table t2'':
SELECT column1,column2,column3 FROM t1 WHERE (column1,column2,column3) IN (SELECT column1,column2,column3 FROM t2);
FROM
clause
Subqueries are legal in a SELECT
statement's FROM
clause.
The syntax that you'll actually see is:
SELECT ... FROM (<subquery>) AS <name> ...
The AS <name>
clause is mandatory, because any table in a
FROM
clause must have a name. Any columns in the <subquery>
select list must have unique names. You may find this syntax described
elsewhere in this manual, where the term used is ``derived tables''.
For illustration, assume you have this table:
CREATE TABLE t1 (s1 INT, s2 CHAR(5), s3 FLOAT);
Here's how to use the Subqueries in the FROM clause feature, using the example table:
INSERT INTO t1 VALUES (1,'1',1.0); INSERT INTO t1 VALUES (2,'2',2.0); SELECT sb1,sb2,sb3 FROM (SELECT s1 AS sb1, s2 AS sb2, s3*2 AS sb3 FROM t1) AS sb WHERE sb1 > 1;
Result: 2, '2', 4.0.
Here's another example: Suppose you want to know the average of the sum for a grouped table. This won't work:
SELECT AVG(SUM(column1)) FROM t1 GROUP BY column1;
But this query will provide the desired information:
SELECT AVG(sum_column1) FROM (SELECT SUM(column1) AS sum_column1 FROM t1 GROUP BY column1) AS t1;
Notice that the column name used within the subquery
(sum_column1)
is recognized in the outer query.
At the moment, subqueries in the FROM
clause cannot be correlated
subqueries.
There are some new error returns which apply only to subqueries. This section groups them together because reviewing them will help remind you of some points.
ERROR 1235 (ER_NOT_SUPPORTED_YET) SQLSTATE = 42000 Message = "This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'"This means that
SELECT * FROM t1 WHERE s1 IN (SELECT s2 FROM t2 ORDER BY s1 LIMIT 1)will not work, but only in some early versions, such as MySQL 4.1.1.
ERROR 1240 (ER_CARDINALITY_COL) SQLSTATE = 21000 Message = "Operand should contain 1 column(s)"This error will occur in cases like this:
SELECT (SELECT column1, column2 FROM t2) FROM t1;It's okay to use a subquery that returns multiple columns, if the purpose is comparison. See section 13.1.8.7 Row Subqueries. But in other contexts the subquery must be a scalar operand.
ERROR 1241 (ER_SUBSELECT_NO_1_ROW) SQLSTATE = 21000 Message = "Subquery returns more than 1 row"This error will occur in cases like this:
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);but only when there is more than one row in
t2
. That means this
error might occur in code that has been working for years, because somebody
happened to make a change which affected the number of rows that the
subquery can return. Remember that if the object is to find any number of
rows, not just one, then the correct statement would look like this:
SELECT * FROM t1 WHERE column1 = ANY (SELECT column1 FROM t2);
Error 1093 (ER_UPDATE_TABLE_USED) SQLSTATE = HY000 Message = "You can't specify target table 'x' for update in FROM clause"This error will occur in cases like this:
UPDATE t1 SET column2 = (SELECT MAX(column1) FROM t1);
It's okay to use a subquery for assignment within an
UPDATE
statement, since subqueries are legal in UPDATE
and in DELETE
statements as well as in SELECT
statements.
However, you cannot use the same table, in this case table t1
, for
both the subquery's FROM
clause and the update target.
Usually, failure of the subquery causes the entire statement to fail.
Development is ongoing, so no optimization tip is reliable for the long term. Some interesting tricks that you might want to play with are:
SELECT * FROM t1 WHERE t1.column1 IN (SELECT column1 FROM t2 ORDER BY column1); SELECT * FROM t1 WHERE t1.column1 IN (SELECT DISTINCT column1 FROM t2); SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 LIMIT 1);
SELECT DISTINCT column1 FROM t1 WHERE t1.column1 IN ( SELECT column1 FROM t2);instead of
SELECT DISTINCT t1.column1 FROM t1, t2 WHERE t1.column1 = t2.column1;
SELECT * FROM t1 WHERE s1 IN (SELECT s1 FROM t1 UNION ALL SELECT s1 FROM t2);instead of
SELECT * FROM t1 WHERE s1 IN (SELECT s1 FROM t1) OR s1 IN (SELECT s1 FROM t2);For another example:
SELECT (SELECT column1 + 5 FROM t1) FROM t2;instead of
SELECT (SELECT column1 FROM t1) + 5 FROM t2;
SELECT * FROM t1 WHERE (column1,column2) IN (SELECT column1,column2 FROM t2);instead of
SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 WHERE t2.column1=t1.column1 AND t2.column2=t1.column2);
NOT (a = ANY (...))
rather than a <> ALL (...)
.
x = ANY (table containing {1,2})
rather than
x=1 OR x=2
.
= ANY
rather than EXISTS
The above tricks may cause programs to go faster or slower. Using MySQL
facilities like the BENCHMARK()
function, you can get an idea about
what helps in your own situation. Don't worry too much about transforming
to joins except for compatibility with older versions.
Some optimizations that MySQL itself will make are:
EXPLAIN
to make sure that a given subquery really is non-correlated),
IN
/ALL
/ANY
/SOME
subqueries
in an attempt to take advantage of the possibility that the select-list
columns in the subquery are indexed,
... IN (SELECT indexed_column FROM single_table ...)with an index-lookup function, which
EXPLAIN
will describe as a
special join type,
value {ALL|ANY|SOME} {> | < | >= | <=} (non-correlated subquery)with an expression involving
MIN
or MAX
(unless NULL
values or empty sets are involved). For example,
WHERE 5 > ALL (SELECT x FROM t)might be treated as
WHERE 5 > (SELECT MAX(x) FROM t)
There is a chapter titled ``How MySQL Transforms Subqueries'' in the MySQL Internals Manual, which you can find by downloading the MySQL source package and looking for a file named `internals.texi'.
Up to version 4.0, only nested queries of the form
INSERT ... SELECT ...
and REPLACE ... SELECT ...
are supported.
The IN()
construct can be used in other contexts.
It is often possible to rewrite a query without a subquery:
SELECT * FROM t1 WHERE id IN (SELECT id FROM t2);
This can be rewritten as:
SELECT t1.* FROM t1,t2 WHERE t1.id=t2.id;
The queries:
SELECT * FROM t1 WHERE id NOT IN (SELECT id FROM t2); SELECT * FROM t1 WHERE NOT EXISTS (SELECT id FROM t2 WHERE t1.id=t2.id);
Can be rewritten as:
SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id WHERE table2.id IS NULL;
A LEFT [OUTER] JOIN
can be faster than an equivalent subquery
because the server might be able to optimize it better -- a fact that is
not specific to MySQL Server alone.
Prior to SQL-92, outer joins did not exist, so subqueries were the only way
to do certain things in those bygone days. Today, MySQL Server and many
other modern database systems offer a whole range of outer joins types.
For more complicated subqueries you can often create temporary tables
to hold the subquery. In some cases, however, this option will not
work. The most frequently encountered of these cases arises with
DELETE
statements, for which standard SQL does not support joins
(except in subqueries). For this situation there are three options
available:
SELECT
query to obtain the primary keys
for the records to be deleted, and then use these values to construct
the DELETE
statement (DELETE FROM ... WHERE ... IN (key1,
key2, ...)
).
DELETE
statements automatically, using the MySQL
extension CONCAT()
(in lieu of the standard ||
operator).
For example:
SELECT CONCAT('DELETE FROM tab1 WHERE pkid = ', "'", tab1.pkid, "'", ';') FROM tab1, tab2 WHERE tab1.col1 = tab2.col2;You can place this query in a script file and redirect input from it to the
mysql
command-line interpreter, piping its output back to a
second instance of the interpreter:
shell> mysql --skip-column-names mydb < myscript.sql | mysql mydb
MySQL Server 4.0 supports multiple-table DELETE
statements that can be used to
efficiently delete rows based on information from one table or even
from many tables at the same time.
Multiple-table UPDATE
statements are also supported from version 4.0.
TRUNCATE
SyntaxTRUNCATE TABLE table_name
In 3.23 TRUNCATE TABLE
is mapped to
COMMIT; DELETE FROM table_name
. See section 13.1.1 DELETE
Syntax.
TRUNCATE TABLE
differs from DELETE FROM ...
in the following ways:
AUTO_INCREMENT
value
but may start counting from the beginning. This is true for
MyISAM
, ISAM
, and BDB
tables.
TRUNCATE TABLE
is an Oracle SQL extension.
This statement was added in MySQL 3.23.28, although from 3.23.28
to 3.23.32, the keyword TABLE
must be omitted.
UPDATE
SyntaxUPDATE [LOW_PRIORITY] [IGNORE] tbl_name SET col_name1=expr1 [, col_name2=expr2 ...] [WHERE where_definition] [ORDER BY ...] [LIMIT row_count]
or:
UPDATE [LOW_PRIORITY] [IGNORE] tbl_name [, tbl_name ...] SET col_name1=expr1 [, col_name2=expr2 ...] [WHERE where_definition]
UPDATE
updates columns in existing table rows with new values.
The SET
clause indicates which columns to modify and the values
they should be given. The WHERE
clause, if given, specifies
which rows should be updated. Otherwise, all rows are updated. If the
ORDER BY
clause is specified, the rows will be updated in the
order that is specified.
If you specify the keyword LOW_PRIORITY
, execution of the
UPDATE
is delayed until no other clients are reading from the table.
If you specify the keyword IGNORE
, the update statement will not
abort even if we get duplicate key errors during the update. Rows that
would cause conflicts will not be updated.
If you access a column from tbl_name
in an expression,
UPDATE
uses the current value of the column. For example, the
following statement sets the age
column to one more than its
current value:
mysql> UPDATE persondata SET age=age+1;
UPDATE
assignments are evaluated from left to right. For example, the
following statement doubles the age
column, then increments it:
mysql> UPDATE persondata SET age=age*2, age=age+1;
If you set a column to the value it currently has, MySQL notices this and doesn't update it.
UPDATE
returns the number of rows that were actually changed.
In MySQL Version 3.22 or later, the C API function mysql_info()
returns the number of rows that were matched and updated and the number of
warnings that occurred during the UPDATE
.
If you update a column that has been declared NOT NULL
by
setting to NULL
, the column is set to the default value appropriate
for the column type and the warning count is incremented. The default
value is is 0
for numeric types, the empty string (''
)
for string types, and the ``zero'' value for date and time types.
Starting from MySQL version 3.23, you can use LIMIT row_count
to
restrict the scope of the UPDATE
. A LIMIT
clause works as
follows:
LIMIT
is a rows-affected restriction.
The statement stops as soon as it has changed row_count
rows that
satisfy the WHERE
clause.
LIMIT
is a rows-matched restriction. The statement
stops as soon as it has found row_count
rows that satisfy the
WHERE
clause, whether or not they actually were changed.
If an ORDER BY
clause is used (available from MySQL 4.0.0), the rows
will be updated in that order. This is really only useful in conjunction
with LIMIT
.
Starting with MySQL Version 4.0.4, you can also perform UPDATE
operations that cover multiple tables:
UPDATE items,month SET items.price=month.price WHERE items.id=month.id;
The example shows an inner join using the comma operator, but
multiple-table UPDATE
statements can use any type of
join allowed in SELECT
statements, such as LEFT JOIN
.
Note: you cannot use ORDER BY
or LIMIT
with multiple-table
UPDATE
.
Before MySQL 4.0.18 one needed the UPDATE
privilege for all
tables used in a multi table UPDATE
(even if they where not
updated). In MySQL 4.0.18 one need the SELECT
privilege for any
columns that are only read.
ALTER DATABASE
SyntaxALTER DATABASE db_name alter_specification [, alter_specification] .... alter_specification: [DEFAULT] CHARACTER SET charset_name | [DEFAULT] COLLATE collation_name
ALTER DATABASE
allows you to change the overall characteristics of
a database.
The CHARACTER SET
clause changes the database character set.
The COLLATE
clause changes the database collation.
Database characteristics are stored in the `db.opt' file in the database directory.
To use ALTER DATABASE
, you need the ALTER
privilege on the
database.
ALTER DATABASE
was added in MySQL 4.1.1.
ALTER TABLE
SyntaxALTER [IGNORE] TABLE tbl_name alter_specification [, alter_specification] ... alter_specification: ADD [COLUMN] create_definition [FIRST | AFTER column_name ] | ADD [COLUMN] (create_definition, create_definition,...) | ADD INDEX [index_name] [index_type] (index_col_name,...) | ADD [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...) | ADD [CONSTRAINT [symbol]] UNIQUE [index_name] [index_type] (index_col_name,...) | ADD FULLTEXT [index_name] (index_col_name,...) | ADD [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...) [reference_definition] | ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT} | CHANGE [COLUMN] old_col_name create_definition [FIRST | AFTER column_name] | MODIFY [COLUMN] create_definition [FIRST | AFTER column_name] | DROP [COLUMN] col_name | DROP PRIMARY KEY | DROP INDEX index_name | DISABLE KEYS | ENABLE KEYS | RENAME [TO] new_tbl_name | ORDER BY col | CHARACTER SET character_set_name [COLLATE collation_name] | table_options
ALTER TABLE
allows you to change the structure of an existing table.
For example, you can add or delete columns, create or destroy indexes, change
the type of existing columns, or rename columns or the table itself. You can
also change the comment for the table and type of the table.
See section 13.2.5 CREATE TABLE
Syntax.
If you use ALTER TABLE
to change a column specification but
DESCRIBE tbl_name
indicates that your column was not changed, it is
possible that MySQL ignored your modification for one of the reasons
described in section 13.2.5.1 Silent Column Specification Changes. For example, if you try to change
a VARCHAR
column to CHAR
, MySQL will still use
VARCHAR
if the table contains other variable-length columns.
ALTER TABLE
works by making a temporary copy of the original table.
The alteration is performed on the copy, then the original table is
deleted and the new one is renamed. This is done in such a way that
all updates are automatically redirected to the new table without
any failed updates. While ALTER TABLE
is executing, the original
table is readable by other clients. Updates and writes to the table
are stalled until the new table is ready.
Note that if you use any other option to ALTER TABLE
than
RENAME
, MySQL will always create a temporary table, even
if the data wouldn't strictly need to be copied (like when you change the
name of a column). We plan to fix this in the future, but as one doesn't
normally do ALTER TABLE
that often this isn't that high on our TODO.
For MyISAM tables, you can speed up the index recreation part (which is the
slowest part of the recreation process) by setting the
myisam_sort_buffer_size
variable to a high value.
ALTER TABLE
, you need ALTER
, INSERT
,
and CREATE
privileges on the table.
IGNORE
is a MySQL extension to SQL-92.
It controls how ALTER TABLE
works if there are duplicates on
unique keys in the new table.
If IGNORE
isn't specified, the copy is aborted and rolled back.
If IGNORE
is specified, then for rows with duplicates on a unique
key, only the first row is used; the others are deleted.
ADD
, ALTER
, DROP
, and
CHANGE
clauses in a single ALTER TABLE
statement. This is a
MySQL extension to SQL-92, which allows only one of each clause
per ALTER TABLE
statement.
CHANGE col_name
, DROP col_name
, and DROP
INDEX
are MySQL extensions to SQL-92.
MODIFY
is an Oracle extension to ALTER TABLE
.
COLUMN
is a pure noise word and can be omitted.
ALTER TABLE tbl_name RENAME TO new_name
without any other
options, MySQL simply renames the files that correspond to the table
tbl_name
. There is no need to create the temporary table.
See section 13.2.9 RENAME TABLE
Syntax.
create_definition
clauses use the same syntax for ADD
and
CHANGE
as for CREATE TABLE
. Note that this syntax includes
the column name, not just the column type.
See section 13.2.5 CREATE TABLE
Syntax.
CHANGE old_col_name create_definition
clause. To do so, specify the old and new column names and the type that
the column currently has. For example, to rename an INTEGER
column
from a
to b
, you can do this:
mysql> ALTER TABLE t1 CHANGE a b INTEGER;If you want to change a column's type but not the name,
CHANGE
syntax still requires an old and new column name, even if they are the same.
For example:
mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;However, as of MySQL Version 3.22.16a, you can also use
MODIFY
to change a column's type without renaming it:
mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
CHANGE
or MODIFY
to shorten a column for which
an index exists on part of the column (for instance, if you have an index
on the first 10 characters of a VARCHAR
column), you cannot make
the column shorter than the number of characters that are indexed.
CHANGE
or MODIFY
,
MySQL tries to convert data to the new type as well as possible.
FIRST
or
ADD ... AFTER col_name
to add a column at a specific position
within a table row. The default is to add the column last.
From MySQL Version 4.0.1, you can also use the FIRST
and
AFTER
keywords in CHANGE
or MODIFY
.
ALTER COLUMN
specifies a new default value for a column
or removes the old default value.
If the old default is removed and the column can be NULL
, the new
default is NULL
. If the column cannot be NULL
, MySQL
assigns a default value, as described in
section 13.2.5 CREATE TABLE
Syntax.
DROP INDEX
removes an index. This is a MySQL extension to
SQL-92. See section 13.2.7 DROP INDEX
Syntax.
DROP TABLE
instead.
DROP PRIMARY KEY
drops the primary index. (Prior to MySQL 4.1.2,
if no primary index exists, DROP PRIMARY KEY
drops the first
UNIQUE
index in the table.
MySQL marks the first UNIQUE
key as the PRIMARY KEY
if no PRIMARY KEY
was specified explicitly.)
If you add a UNIQUE INDEX
or PRIMARY KEY
to a table, this
is stored before any not UNIQUE
index so that MySQL can detect
duplicate keys as early as possible.
ORDER BY
allows you to create the new table with the rows in a
specific order. Note that the table will not remain in this order after
inserts and deletes. In some cases, it may make sorting easier for
MySQL if the table is in order by the column that you wish to
order it by later. This option is mainly useful when you know that you
are mostly going to query the rows in a certain order; by using this
option after big changes to the table, you may be able to get higher
performance.
ALTER TABLE
on a MyISAM
table, all non-unique
indexes are created in a separate batch (like in REPAIR
).
This should make ALTER TABLE
much faster when you have many indexes.
ALTER TABLE ... DISABLE KEYS
makes MySQL to stop updating
non-unique indexes for MyISAM
table.
ALTER TABLE ... ENABLE KEYS
then should be used to recreate missing
indexes. As MySQL does it with a special algorithm which is much
faster then inserting keys one by one, disabling keys could give a
considerable speedup on bulk inserts.
mysql_info()
, you can find out how many
records were copied, and (when IGNORE
is used) how many records were
deleted due to duplication of unique key values.
FOREIGN KEY
, CHECK
, and REFERENCES
clauses don't
actually do anything, except for InnoDB type tables which support
... ADD [CONSTRAINT [symbol]] FOREIGN KEY (...) REFERENCES ... (...)
and ... DROP FOREIGN KEY ...
.
See section 14.4.5.2 FOREIGN KEY
Constraints.
The syntax for other table types is provided only for compatibility,
to make it easier to port code from other SQL servers and to run applications
that create tables with references.
See section 1.8.5 MySQL Differences Compared to SQL-92.
ALTER TABLE
ignores the DATA DIRECTORY
and INDEX
DIRECTORY
table options.
ALTER TABLE table_name CHARACTER SET character_set_name;Note that the following command will only change the
default character
set
for a table:
ALTER TABLE table_name DEFAULT CHARACTER SET character_set_name;The
default character set
is the character set that is used if
you don't specify the character set for a new column you add to a table
(for example with ALTER TABLE ... ADD column
).
Here is an example that shows some of the uses of ALTER TABLE
. We
begin with a table t1
that is created as shown here:
mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10));
To rename the table from t1
to t2
:
mysql> ALTER TABLE t1 RENAME t2;
To change column a
from INTEGER
to TINYINT NOT NULL
(leaving the name the same), and to change column b
from
CHAR(10)
to CHAR(20)
as well as renaming it from b
to
c
:
mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);
To add a new TIMESTAMP
column named d
:
mysql> ALTER TABLE t2 ADD d TIMESTAMP;
To add an index on column d
, and make column a
the primary key:
mysql> ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a);
To remove column c
:
mysql> ALTER TABLE t2 DROP COLUMN c;
To add a new AUTO_INCREMENT
integer column named c
:
mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT, ADD INDEX (c);
Note that we indexed c
, because AUTO_INCREMENT
columns must be
indexed, and also that we declare c
as NOT NULL
, because
indexed columns cannot be NULL
.
When you add an AUTO_INCREMENT
column, column values are filled in
with sequence numbers for you automatically. You can set the first
sequence number by executing SET INSERT_ID=value
before
ALTER TABLE
or using the AUTO_INCREMENT=value
table option.
See section 7.5.6 SET
Syntax.
With MyISAM tables, if you don't change the AUTO_INCREMENT
column, the sequence number will not be affected. If you drop an
AUTO_INCREMENT
column and then add another AUTO_INCREMENT
column, the numbers will start from 1 again.
See section A.7.1 Problems with ALTER TABLE
..
CREATE DATABASE
SyntaxCREATE DATABASE [IF NOT EXISTS] db_name [create_specification [, create_specification] ...] create_specification: [DEFAULT] CHARACTER SET charset_name | [DEFAULT] COLLATE collation_name
CREATE DATABASE
creates a database with the given name.
Rules for
allowable database names are given in section 10.2 Database, Table, Index, Column, and Alias Names. An error occurs if
the database already exists and you didn't specify IF NOT EXISTS
.
As of MySQL 4.1.1, create_specification
options may be given.
The CHARACTER SET
clause specifies the database character set.
The COLLATE
clause specifies the database collation.
Database characteristics are stored in the `db.opt' file in the database directory.
Databases in MySQL are implemented as directories containing files
that correspond to tables in the database. Because there are no tables in a
database when it is initially created, the CREATE DATABASE
statement
only creates a directory under the MySQL data directory.
You can also create databases with mysqladmin
.
See section 8 MySQL Client and Utility Programs.
CREATE INDEX
SyntaxCREATE [UNIQUE|FULLTEXT] INDEX index_name [index_type] ON tbl_name (index_col_name,...) index_col_name: col_name [(length)] [ASC | DESC]
The CREATE INDEX
statement doesn't do anything in MySQL prior
to Version 3.22. In Version 3.22 or later, CREATE INDEX
is mapped to an
ALTER TABLE
statement to create indexes.
See section 13.2.2 ALTER TABLE
Syntax.
Normally, you create all indexes on a table at the time the table itself
is created with CREATE TABLE
.
See section 13.2.5 CREATE TABLE
Syntax.
CREATE INDEX
allows you to add indexes to existing tables.
A column list of the form (col1,col2,...)
creates a multiple-column
index. Index values are formed by concatenating the values of the given
columns.
For CHAR
and VARCHAR
columns, indexes can be created that
use only part of a column, using col_name(length)
syntax to index the
first length
bytes of each column value. (For
BLOB
and TEXT
columns, a prefix length is required;
length
may be a value up to 255.) The
statement shown here creates an index using the first 10 characters of
the name
column:
mysql> CREATE INDEX part_of_name ON customer (name(10));
Because most names usually differ in the first 10 characters, this index should
not be much slower than an index created from the entire name
column.
Also, using partial columns for indexes can make the index file much smaller,
which could save a lot of disk space and might also speed up INSERT
operations!
Note that you can add an index on a column that can have NULL
values only if you are using MySQL Version 3.23.2 or newer and are using the
MyISAM
, InnoDB
, or BDB
table type.
You can only add an index on a BLOB
/TEXT
column if you are using
MySQL Version 3.23.2 or newer and are using the MyISAM
or BDB
table type, or MySQL Version 4.0.14 or newer and the InnoDB
table type.
For an index on a BLOB
or TEXT
column, a prefix length must always
be specified.
An index_col_name
specification may end with ASC
or DESC
.
These keywords are allowed for future extensions for specifying ascending
or descending index value storage. Currently they are parsed but ignored;
index values are always stored in ascending order.
For more information about how MySQL uses indexes, see section 7.4.3 How MySQL Uses Indexes.
FULLTEXT
indexes can index only CHAR
, VARCHAR
, and
TEXT
columns, and only in MyISAM
tables. FULLTEXT
indexes
are available in MySQL Version 3.23.23 and later.
section 13.7 MySQL Full-text Search.
CREATE TABLE
SyntaxCREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)] [table_options] [select_statement]
or:
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(] LIKE old_tbl_name [)]; create_definition: col_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT] [[PRIMARY] KEY] [COMMENT 'string'] [reference_definition] | [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...) | KEY [index_name] [index_type] (index_col_name,...) | INDEX [index_name] [index_type] (index_col_name,...) | [CONSTRAINT [symbol]] UNIQUE [INDEX] [index_name] [index_type] (index_col_name,...) | FULLTEXT [INDEX] [index_name] (index_col_name,...) | [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...) [reference_definition] | CHECK (expr) type: TINYINT[(length)] [UNSIGNED] [ZEROFILL] | SMALLINT[(length)] [UNSIGNED] [ZEROFILL] | MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL] | INT[(length)] [UNSIGNED] [ZEROFILL] | INTEGER[(length)] [UNSIGNED] [ZEROFILL] | BIGINT[(length)] [UNSIGNED] [ZEROFILL] | REAL[(length,decimals)] [UNSIGNED] [ZEROFILL] | DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL] | FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL] | DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL] | NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL] | CHAR(length) [BINARY | ASCII | UNICODE] | VARCHAR(length) [BINARY] | DATE | TIME | TIMESTAMP | DATETIME | TINYBLOB | BLOB | MEDIUMBLOB | LONGBLOB | TINYTEXT | TEXT | MEDIUMTEXT | LONGTEXT | ENUM(value1,value2,value3,...) | SET(value1,value2,value3,...) index_col_name: col_name [(length)] [ASC | DESC] reference_definition: REFERENCES tbl_name [(index_col_name,...)] [MATCH FULL | MATCH PARTIAL] [ON DELETE reference_option] [ON UPDATE reference_option] reference_option: RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT table_options: table_option [table_option] ... table_option: {ENGINE | TYPE} = {BDB | HEAP | ISAM | InnoDB | MERGE | MRG_MYISAM | MYISAM} | AUTO_INCREMENT = # | AVG_ROW_LENGTH = # | CHECKSUM = {0 | 1} | COMMENT = 'string' | MAX_ROWS = # | MIN_ROWS = # | PACK_KEYS = {0 | 1 | DEFAULT} | PASSWORD = 'string' | DELAY_KEY_WRITE = {0 | 1} | ROW_FORMAT = { DEFAULT | DYNAMIC | FIXED | COMPRESSED } | RAID_TYPE = { 1 | STRIPED | RAID0 } RAID_CHUNKS=# RAID_CHUNKSIZE=# | UNION = (table_name,[table_name...]) | INSERT_METHOD = { NO | FIRST | LAST } | DATA DIRECTORY = 'absolute path to directory' | INDEX DIRECTORY = 'absolute path to directory' | DEFAULT CHARACTER SET character_set_name [COLLATE collation_name] select_statement: [IGNORE | REPLACE] [AS] SELECT ... (Some legal select statement)
CREATE TABLE
creates a table with the given name.
Rules for allowable table names are given in section 10.2 Database, Table, Index, Column, and Alias Names.
By default, the table is created in the current database.
An error occurs if the table already exists, if there is no current database,
or if the database does not exist.
In MySQL Version 3.22 or later, the table name can be specified as
db_name.tbl_name
to create the table in a specific database.
This works regardless of whether there is a current database.
From MySQL Version 3.23, you can use the TEMPORARY
keyword when
you create a table. The temporary table is visible only to the
current connection, and will be deleted automatically when the
connection is closed. This means that two different
connections can both use the same temporary table name without conflicting
with each other or with an existing table of the same name. (The existing table
is hidden until the temporary table is deleted.) From MySQL 4.0.2 on, you must
have the CREATE TEMPORARY TABLES
privilege to be able to create
temporary tables.
In MySQL Version 3.23 or later, you can use the keywords
IF NOT EXISTS
so that an error does not occur if the table already
exists. Note that there is no verification that the existing table has a
structure identical to that indicated by the CREATE TABLE
statement.
From version 4.1.0, the attribute SERIAL
can be used as an alias for
BIGINT NOT NULL AUTO_INCREMENT UNIQUE
. This is compatibility feature.
As of MySQL 3.23, you can create one table from another by adding a
SELECT
statement at the end of the CREATE TABLE
statement:
CREATE TABLE new_tbl SELECT * FROM orig_tbl;
Indexes are not carried over to the new table, and some conversion of column
types may occur. For example, the AUTO_INCREMENT
attribute is not
preserved, and VARCHAR
columns may become CHAR
columns.
When creating a table with CREATE ... SELECT
, make sure to alias any
function calls or expressions in the query. If you do not, the CREATE
statement may fail or result in undesirable column names.
CREATE TABLE artists_and_works SELECT artist.name, COUNT(work.artist_id) AS number_of_works FROM artist LEFT JOIN work ON artist.id = work.artist_id GROUP BY artist.id;
As of MySQL 4.1, you can explicitly specify the type for a generated column:
CREATE TABLE foo (a tinyint not null) SELECT b+1 AS 'a' FROM bar;
In MySQL 4.1, you can also use LIKE
to create a table based on the
definition of another table, including any column attributes and
indexes the original table has:
CREATE TABLE new_tbl LIKE orig_tbl;
CREATE TABLE ... LIKE
does not copy any DATA DIRECTORY
or
INDEX DIRECTORY
table options that were specified for the original
table.
Each table tbl_name
is represented by some files in the database
directory. In the case of MyISAM
-type tables you will get:
File | Purpose |
tbl_name.frm | Table format (definition) file |
tbl_name.MYD | Datafile |
tbl_name.MYI | Index file |
For more information on the properties of the various column types, see section 11 Column Types:
NULL
nor NOT NULL
is specified, the column
is treated as though NULL
had been specified.
AUTO_INCREMENT
.
When you insert a value of NULL
(recommended) or 0
into an
indexed
AUTO_INCREMENT
column, the column is set to the next sequence value.
Typically this is value+1
, where
value
is the largest value for the column currently in the table.
AUTO_INCREMENT
sequences begin with 1
.
See section 19.1.3.32 mysql_insert_id()
.
As of MySQL 4.1.1, specifying the NO_AUTO_VALUE_ON_ZERO
flag for the
--sql-mode
server option or the sql_mode
server variable allows
you to store 0
in AUTO_INCREMENT
columns as 0
, instead
of generating a new sequence value.
See section 5.2.1 mysqld
Command-line Options.
If you delete the row containing the maximum value for an
AUTO_INCREMENT
column, the value will be reused for an
ISAM
or BDB
table, but not for a
MyISAM
or InnoDB
table. If you delete all rows in the table
with DELETE FROM table_name
(without a WHERE
) in
AUTOCOMMIT
mode, the sequence starts over for all table types except
InnoDB
. See section 14.4.12.5 How an AUTO_INCREMENT
Column Works in InnoDB.
Note: there can be only one AUTO_INCREMENT
column per
table, it must be indexed and it can't have a DEFAULT
value.
In MySQL Version 3.23, an AUTO_INCREMENT
column will work properly
only if it contains only positive values. Inserting a
negative number is regarded as inserting a very large positive number.
This is done to avoid precision problems when numbers ``wrap'' over from
positive to negative and also to ensure that one doesn't accidentally
get an AUTO_INCREMENT
column that contains 0.
In MyISAM
and BDB
tables you can specify AUTO_INCREMENT
secondary column in a multiple-column key. See section 3.6.9 Using AUTO_INCREMENT
.
To make MySQL compatible with some ODBC applications, you can find the
AUTO_INCREMENT
value for the last inserted row with the following query:
SELECT * FROM tbl_name WHERE auto_col IS NULL
NULL
values are handled differently for TIMESTAMP
columns than
for other column types. You cannot store a literal NULL
in a
TIMESTAMP
column; setting the column to NULL
sets it to the
current date and time. Because TIMESTAMP
columns behave this way, the
NULL
and NOT NULL
attributes do not apply in the normal way and
are ignored if you specify them.
On the other hand, to make it easier for MySQL clients to use
TIMESTAMP
columns, the server reports that such columns may be
assigned NULL
values (which is true), even though TIMESTAMP
never actually will contain a NULL
value. You can see this when you
use DESCRIBE tbl_name
to get a description of your table.
Note that setting a TIMESTAMP
column to 0
is not the same
as setting it to NULL
, because 0
is a valid TIMESTAMP
value.
DEFAULT
value has to be a constant, it cannot be a function or
an expression.
If no DEFAULT
value is specified for a column, MySQL
automatically assigns one, as follows.
If the column may take NULL
as a value, the default value is
NULL
.
If the column is declared as NOT NULL
, the default value depends on
the column type:
AUTO_INCREMENT
attribute, the default is 0
. For an AUTO_INCREMENT
column, the
default value is the next value in the sequence.
TIMESTAMP
, the default is the
appropriate zero value for the type. For the first TIMESTAMP
column in a table, the default value is the current date and time.
See section 11.2 Date and Time Types.
ENUM
, the default value is the empty
string. For ENUM
, the default is the first enumeration value.
NOW()
or CURRENT_DATE
.
COMMENT
option.
The comment is displayed by the
SHOW CREATE TABLE
statement, and by SHOW FULL COLUMNS
.
This option is available as of MySQL 4.1.
(It is allowed but ignored in earlier versions.)
KEY
is normally a synonym for INDEX
.
From version 4.1, the key attribute PRIMARY KEY
may also be
specified as just KEY
. This was implemented for compatibility
with other databases.
UNIQUE
key can have only distinct values. An
error occurs if you try to add a new row with a key that matches an existing
row.
PRIMARY KEY
is a unique KEY
where all key columns must be
defined as NOT NULL
. If they are not explicitly declared as
NOT NULL
, it will be done implicitly (and quietly). In MySQL
the key is named PRIMARY
. A table can have only one PRIMARY KEY
.
If you don't have a PRIMARY KEY
and some applications ask for the
PRIMARY KEY
in your tables, MySQL will return the first
UNIQUE
key, which doesn't have any NULL
columns, as the
PRIMARY KEY
.
PRIMARY KEY
can be a multiple-column index. However, you cannot
create a multiple-column index using the PRIMARY KEY
key attibute in a
column specification. Doing so will mark only that single column as primary.
You must use a separate PRIMARY KEY(index_col_name, ...)
clause.
UNIQUE
index is one in which all values in the index must be
distinct. The exception to this is that if a column in the index is allowed
to contain NULL
values, it may contain multiple NULL
values.
This exception does not apply to BDB
tables, which allow only a single
NULL
.
PRIMARY
or UNIQUE
key consists of only one column and this
is of type integer, you can also refer to it as _rowid
(new in Version 3.23.11).
PRIMARY KEY
,
the index will be assigned the same
name as the first index_col_name
, with an optional suffix (_2
,
_3
, ...
) to make it unique. You can see index names for a
table using SHOW INDEX FROM tbl_name
.
See section 13.5.3.1 Retrieving Information about Database, Tables, Columns, and Indexes.
index_type
specifier is USING type_name
. The allowable type_name
values supported by different storage engines are shown in the following
table. Where multiple index types are listed, the first one is the
default when no index_type
specifier is given.
Storage engine | Allowable index types |
MyISAM | BTREE
|
InnoDB | BTREE
|
MEMORY/HEAP | HASH , BTREE
|
CREATE TABLE lookup (id INT, INDEX USING BTREE (id)) ENGINE = MEMORY;
TYPE type_name
may be used as a synonym for USING type_name
to specify an index type. USING
is the preferred form, however.
(The preceding index name is not optional with TYPE
, because unlike
USING
, TYPE
is not a reserved word and thus is interpreted
as an index name.)
MyISAM
, InnoDB
, and BDB
table types support indexes on columns that can have
NULL
values. In other cases you must declare such columns
NOT NULL
or an error results.
col_name(length)
syntax in an index specification, you can create
an index that uses only the first length
bytes of a CHAR
or VARCHAR
column. This can make the index file much smaller.
See section 7.4.4 Column Indexes.
MyISAM
and (as of MySQL 4.0.14)
InnoDB
table types support indexing on BLOB
and
TEXT
columns. When putting an index on a BLOB
or TEXT
column you MUST always specify the length of the index, up to 255 bytes. For
example:
CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
index_col_name
specification may end with ASC
or DESC
.
These keywords are allowed for future extensions for specifying ascending
or descending index value storage. Currently they are parsed but ignored;
index values are always stored in ascending order.
ORDER BY
or GROUP BY
with a TEXT
or
BLOB
column, the server sorts values using only the initial number of
bytes indicated by the max_sort_length
server variable.
See section 11.3.2 The BLOB
and TEXT
Types.
FULLTEXT
indexes. They are used for full-text search. Only the
MyISAM
table type supports FULLTEXT
indexes. They can be created
only from CHAR
, VARCHAR
, and TEXT
columns.
Indexing always happens over the entire column; partial indexing is not
supported. See section 13.7 MySQL Full-text Search for details of operation.
InnoDB
tables support checking of
foreign key constraints. See section 14.4 InnoDB
Tables. Note that the
FOREIGN KEY
syntax in InnoDB
is more restrictive than
the syntax presented above: The columns of the referenced
table must always be explicitly named.
InnoDB supports both ON DELETE
and ON UPDATE
actions on foreign keys as of MySQL 3.23.50 and 4.0.8, respectively.
See the InnoDB
manual section for the precise syntax.
See section 14.4.5.2 FOREIGN KEY
Constraints.
For other table types, MySQL Server does parse the FOREIGN KEY
,
CHECK
, and REFERENCES
syntax in CREATE TABLE
commands,
but without further action being taken. See section 1.8.5.5 Foreign Keys.
MyISAM
and ISAM
tables,
each NULL
column takes one bit extra, rounded up to the nearest byte.
The maximum record length in bytes can be calculated as follows:
row length = 1 + (sum of column lengths) + (number of NULL columns + delete_flag + 7)/8 + (number of variable-length columns)
delete_flag
is 1 for tables with static record format. Static
tables use a bit in the row record for a flag that indicates whether
the row has been deleted. delete_flag
is 0 for dynamic tables
because the flag is stored in the dynamic row header.
These calculations do not apply for InnoDB
tables, for which
storage size is not different for NULL
columns compared to NOT
NULL
columns.
table_options
and SELECT
options are only
implemented in MySQL Version 3.23 and above.
The ENGINE
and TYPE
options specify the storage engine for the
table. ENGINE
was added in MySQL 4.0.18 (for 4.0) and 4.1.2 (for 4.1).
It is the preferred option name as of those versions, and TYPE
has
become deprecated. TYPE
will be supported throughout the 4.x series,
but likely will be removed in MySQL 5.1.
The ENGINE
and TYPE
options take the following values:
Storage engine | Description |
BDB or BerkeleyDB | Transaction-safe tables with page locking. See section 14.5 BDB or BerkeleyDB Tables.
|
HEAP | The data for this table is only stored in memory. See section 14.3 HEAP Tables.
|
ISAM | The original storage engine. See section 14.6 ISAM Tables.
|
InnoDB | Transaction-safe tables with row locking. See section 14.4 InnoDB Tables.
|
MERGE | A collection of MyISAM tables used as one table. See section 14.2 MERGE Tables.
|
MRG_MyISAM | An alias for MERGE .
|
MyISAM | The new binary portable storage engine that is the replacement for ISAM . See section 14.1 MyISAM Tables.
|
MyISAM
instead.
For example, if a table definition includes the ENGINE=BDB
option but the
MySQL server does not support BDB
tables, the table will be created
as a MyISAM
table. This makes it possible to have a replication
setup where you have transactional tables on the master but tables created
on the slave are non-transactional (to get more speed). In MySQL 4.1.1 you
get a warning if the specified table type is not honored.
The other table options are used to optimize the behavior of the
table. In most cases, you don't have to specify any of them.
The options work for all table types, unless otherwise indicated:
Option | Description |
AUTO_INCREMENT | The next AUTO_INCREMENT value you want to set for your table (MyISAM only; to set the first auto-increment value for an InnoDB table, insert a dummy row with a value one less, and delete the dummy row).
|
AVG_ROW_LENGTH | An approximation of the average row length for your table. You only need to set this for large tables with variable size records. |
CHECKSUM | Set this to 1 if you want MySQL to maintain a checksum for all rows (makes the table a little slower to update but makes it easier to find corrupted tables) (MyISAM only).
|
COMMENT | A 60-character comment for your table. |
MAX_ROWS | Maximum number of rows you plan to store in the table. |
MIN_ROWS | Minimum number of rows you plan to store in the table. |
PACK_KEYS | Set this to 1 if you want to have a smaller index. This usually makes updates slower and reads faster (MyISAM and ISAM only). Setting this to 0 will disable all packing of keys. Setting this to DEFAULT (MySQL 4.0) will tell the storage engine to only pack long CHAR /VARCHAR columns.
|
PASSWORD | Encrypt the `.frm' file with a password. This option doesn't do anything in the standard MySQL version. |
DELAY_KEY_WRITE | Set this to 1 if want to delay key table updates until the table is closed (MyISAM only).
|
ROW_FORMAT | Defines how the rows should be stored. Currently this option only works with MyISAM tables, which supports the DYNAMIC and FIXED row formats. See section 14.1.2 MyISAM Table Formats.
|
MyISAM
table, MySQL uses the product of
MAX_ROWS * AVG_ROW_LENGTH
to decide how big the resulting table
will be. If you don't specify any of the above options, the maximum size
for a table will be 4G (or 2G if your operating systems only supports 2G
tables). The reason for this is just to keep down the pointer sizes
to make the index smaller and faster if you don't really need big files.
If you don't use PACK_KEYS
, the default is to only pack strings,
not numbers. If you use PACK_KEYS=1
, numbers will be packed as well.
When packing binary number keys, MySQL will use prefix compression.
This means that you will only get a big benefit from this if you have
many numbers that are the same. Prefix compression means that every
key needs one extra byte to indicate how many bytes of the previous key are
the same for the next key (note that the pointer to the row is stored
in high-byte-first order directly after the key, to improve
compression). This means that if you have many equal keys on two consecutive
rows, all following ``same'' keys will usually only take 2 bytes
(including the pointer to the row). Compare this to the ordinary case
where the following keys will take storage_size_for_key +
pointer_size (usually 4). On the other hand, if all keys are
totally different, you will use 1 byte more per key, if the key isn't a
key that can have NULL
values. (In this case the packed key length will
be stored in the same byte that is used to mark if a key is NULL
.)
SELECT
after the CREATE
statement,
MySQL will create new fields for all elements in the
SELECT
. For example:
mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT, -> PRIMARY KEY (a), KEY(b)) -> TYPE=MyISAM SELECT b,c FROM test2;This will create a
MyISAM
table with three columns, a, b, and c.
Notice that the columns from the SELECT
statement are appended to
the right side of the table, not overlapped onto it. Take the following
example:
mysql> SELECT * FROM foo; +---+ | n | +---+ | 1 | +---+ mysql> CREATE TABLE bar (m INT) SELECT n FROM foo; Query OK, 1 row affected (0.02 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM bar; +------+---+ | m | n | +------+---+ | NULL | 1 | +------+---+ 1 row in set (0.00 sec)For each row in table
foo
, a row is inserted in bar
with
the values from foo
and default values for the new columns.
CREATE TABLE ... SELECT
will not automatically create any indexes
for you. This is done intentionally to make the command as flexible as
possible. If you want to have indexes in the created table, you should
specify these before the SELECT
statement:
mysql> CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;If any errors occur while copying the data to the table, it will automatically be deleted. You can precede the
SELECT
by IGNORE
or REPLACE
to indicate how to handle records that duplicate unique key values.
With IGNORE
, new records that duplicate an existing record on a
unique key value are discarded. With REPLACE
, new records replace
records that have the same unique key value. If neither IGNORE
nor REPLACE
are specified, duplicate unique key values result in
an error.
To ensure that the update log/binary log can be used to re-create the
original tables, MySQL will not allow concurrent inserts during
CREATE TABLE ... SELECT
.
RAID_TYPE
option will help you to exceed the 2G/4G limit for
the MyISAM datafile (not the index file) on operating systems that
don't support big files. Note that this option is not recommended for
filesystem that supports big files!
You can get more speed from the I/O bottleneck by putting RAID
directories on different physical disks. RAID_TYPE
will work on
any operating system, as long as you have built MySQL with the
--with-raid
option to configure
. For now the only allowed
RAID_TYPE
is STRIPED
(1
and RAID0
are aliases
for this).
If you specify RAID_TYPE=STRIPED
for a MyISAM
table,
MyISAM
will create RAID_CHUNKS
subdirectories named 00,
01, 02 in the database directory. In each of these directories
MyISAM
will create a table_name.MYD
. When writing data
to the datafile, the RAID
handler will map the first
RAID_CHUNKSIZE
*1024 bytes to the first file, the next
RAID_CHUNKSIZE
*1024 bytes to the next file and so on.
UNION
is used when you want to use a collection of identical
tables as one. This only works with MERGE
tables.
See section 14.2 MERGE
Tables.
For the moment you need to have SELECT
, UPDATE
, and
DELETE
privileges on the tables you map to a MERGE
table.
All mapped tables must be in the same database as the MERGE
table.
MERGE
table, you have to specify with
INSERT_METHOD
into with table the row should be inserted.
INSERT_METHOD
is an option useful for MERGE
tables only.
See section 14.2 MERGE
Tables. This option was introduced in MySQL 4.0.0.
PRIMARY
key will be placed first, followed
by all UNIQUE
keys and then the normal keys. This helps the
MySQL optimizer to prioritize which key to use and also more quickly
detect duplicated UNIQUE
keys.
DATA DIRECTORY='directory'
or INDEX
DIRECTORY='directory'
you can specify where the storage engine should
put its datafile and index file. Note that the directory should be a full
path to the directory (not a relative path).
This only works for MyISAM
tables in MySQL
4.0, when you
are not using the --skip-symlink
option. Your operating system
must also have a working, thread-safe realpath()
call. See section 7.6.1.2 Using Symbolic Links for Tables on Unix.
In some cases, MySQL silently changes a column specification from
that given in a CREATE TABLE
statement. (This may also occur with
ALTER TABLE
.):
VARCHAR
columns with a length less than four are changed to
CHAR
.
VARCHAR
, TEXT
, or BLOB
),
all CHAR
columns longer than three characters are changed to
VARCHAR
columns. This doesn't affect how you use the columns in
any way; in MySQL, VARCHAR
is just a different way to
store characters. MySQL performs this conversion because it
saves space and makes table operations faster. See section 14 MySQL Table Types.
CHAR
or VARCHAR
field with a
length specification greater than 255 is converted to TEXT
.
This is a compatibility feature.
TIMESTAMP
display sizes must be even and in the range from 2 to 14.
If you specify a display size of 0 or greater than 14, the size is coerced
to 14. Odd-valued sizes in the range from 1 to 13 are coerced
to the next higher even number.
NULL
in a TIMESTAMP
column; setting
it to NULL
sets it to the current date and time. Because
TIMESTAMP
columns behave this way, the NULL
and NOT NULL
attributes do not apply in the normal way and are ignored if you specify
them. DESCRIBE tbl_name
always reports that a TIMESTAMP
column may be assigned NULL
values.
If you want to see whether MySQL used a column type other
than the one you specified, issue a DESCRIBE tbl_name
statement after
creating or altering your table.
Certain other column type changes may occur if you compress a table
using myisampack
. See section 14.1.2.3 Compressed Table Characteristics.
DROP DATABASE
SyntaxDROP DATABASE [IF EXISTS] db_name
DROP DATABASE
drops all tables in the database and deletes the
database. If you do a DROP DATABASE
on a symbolic linked
database, both the link and the original database is deleted. Be
VERY careful with this command!
DROP DATABASE
returns the number of files that were removed from
the database directory. For MyISAM
tables, this is three times the number of
tables, because normally each table corresponds to a `.MYD' file, a
`.MYI' file, and a `.frm' file.
The DROP DATABASE
command removes from the given database
directory all files with the following extensions:
Ext | Ext | Ext | Ext |
.BAK | .DAT | .HSH | .ISD |
.ISM | .ISM | .MRG | .MYD |
.MYI | .db | .frm |
All subdirectories that consists of 2 digits (RAID
directories)
are also removed.
In MySQL Version 3.22 or later, you can use the keywords
IF EXISTS
to prevent an error from occurring if the database doesn't
exist.
You can also drop databases with mysqladmin
. See section 8 MySQL Client and Utility Programs.
DROP INDEX
SyntaxDROP INDEX index_name ON tbl_name
DROP INDEX
drops the index named index_name
from the table
tbl_name
. DROP INDEX
doesn't do anything in MySQL
prior to Version 3.22. In Version 3.22 or later, DROP INDEX
is mapped to an
ALTER TABLE
statement to drop the index.
See section 13.2.2 ALTER TABLE
Syntax.
DROP TABLE
SyntaxDROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name,...] [RESTRICT | CASCADE]
DROP TABLE
removes one or more tables. All table data and the table
definition are removed, so be careful with this command!
In MySQL Version 3.22 or later, you can use the keywords
IF EXISTS
to prevent an error from occurring for tables that don't
exist. In 4.1 one gets a NOTE
for all not existing tables when using
IF EXISTS
. See section 13.5.3.9 SHOW WARNINGS | ERRORS
.
RESTRICT
and CASCADE
are allowed to make porting easier.
For the moment they don't do anything.
Note: DROP TABLE
will automatically commit current
active transaction (except if you are using 4.1 and the TEMPORARY
key word.
Option TEMPORARY
is ignored in 4.0. In 4.1 this option works as
follows:
Using TEMPORARY
is a good way to ensure that you don't accidently
drop a real table.
RENAME TABLE
SyntaxRENAME TABLE tbl_name TO new_tbl_name[, tbl_name2 TO new_tbl_name2,...]
The rename is done atomically, which means that no other thread can access any of the tables while the rename is running. This makes it possible to replace a table with an empty one :
CREATE TABLE new_table (...); RENAME TABLE old_table TO backup_table, new_table TO old_table;
The rename is done from left to right, which means that if you want to swap two table names, you have to:
RENAME TABLE old_table TO backup_table, new_table TO old_table, backup_table TO new_table;
As long as two databases are on the same disk you can also rename from one database to another:
RENAME TABLE current_db.tbl_name TO other_db.tbl_name;
When you execute RENAME
, you can't have any locked tables or
active transactions. You must also have the ALTER
and DROP
privileges on the original table, and the CREATE
and INSERT
privileges on the new table.
If MySQL encounters any errors in a multiple-table rename, it will do a reverse rename for all renamed tables to get everything back to the original state.
RENAME TABLE
was added in MySQL 3.23.23.
DESCRIBE
Syntax (Get Information About Columns){DESCRIBE | DESC} tbl_name [col_name | wild]
DESCRIBE
is a shortcut for SHOW COLUMNS FROM
.
See section 13.5.3.1 Retrieving Information about Database, Tables, Columns, and Indexes.
DESCRIBE
provides information about a table's columns. col_name
may be a column name or a string containing the SQL `%' and `_'
wildcard characters to obtain output only for the columns with names matching
the string. There is no need to enclose the string in quotes.
If the column types are different from what you expect them to be based on a
CREATE TABLE
statement, note that MySQL sometimes
changes column types. See section 13.2.5.1 Silent Column Specification Changes.
This statement is provided for Oracle compatibility.
The SHOW
statement provides similar information.
See section 13.5.3 SHOW
Syntax.
USE
SyntaxUSE db_name
The USE db_name
statement tells MySQL to use the db_name
database as the default database for subsequent queries. The database remains
current until the end of the session or until another USE
statement
is issued:
mysql> USE db1; mysql> SELECT COUNT(*) FROM mytable; # selects from db1.mytable mysql> USE db2; mysql> SELECT COUNT(*) FROM mytable; # selects from db2.mytable
Making a particular database current by means of the USE
statement
does not preclude you from accessing tables in other databases. The following example
accesses the author
table from the db1
database and the
editor
table from the db2
database:
mysql> USE db1; mysql> SELECT author_name,editor_name FROM author,db2.editor -> WHERE author.editor_id = db2.editor.editor_id;
The USE
statement is provided for Sybase compatibility.
START TRANSACTION
, COMMIT
, and ROLLBACK
SyntaxBy default, MySQL runs in autocommit mode. This means that as soon as you execute a statement that updates (modifies) a table, MySQL will store the update on disk.
If you are using transaction-safe tables (like InnoDB
or BDB
),
you can put MySQL into non-autocommit mode with the following command:
SET AUTOCOMMIT=0
After disabling autocommit mode by setting the AUTOCOMMIT
variable to
zero, you must use COMMIT
to store your changes to disk or
ROLLBACK
if you want to ignore the changes you have made since
the beginning of your transaction.
If you want to disable autocommit mode for a single series of
statements, you can use the START TRANSACTION
statement:
:
START TRANSACTION; SELECT @A:=SUM(salary) FROM table1 WHERE type=1; UPDATE table2 SET summmary=@A WHERE type=1; COMMIT;
BEGIN
and BEGIN WORK
can be used instead of
START TRANSACTION
to initiate a transaction.
START TRANSACTION
was added in MySQL 4.0.11; it is SQL-99 syntax and
is the recommended way to start an ad-hoc transaction. BEGIN
and
BEGIN WORK
are available from MySQL 3.23.17 and 3.23.19, respectively.
Note that if you are not using transaction-safe tables, any changes will be stored at once, regardless of the status of autocommit mode.
If you issue a ROLLBACK
statement after updating a non-transactional
table, you will get an error (ER_WARNING_NOT_COMPLETE_ROLLBACK
) as
a warning. All transaction-safe tables will be restored but any
non-transaction-safe table will not change.
If you are using START TRANSACTION
or SET AUTOCOMMIT=0
, you
should use the MySQL binary log for backups instead of the
older update log. Transactions are stored in the binary log
in one chunk, upon COMMIT
, to ensure that transactions that are
rolled back are not stored. See section 5.7.4 The Binary Log.
You can change the isolation level for transactions with
SET TRANSACTION ISOLATION LEVEL
.
See section 13.4.6 SET TRANSACTION
Syntax.
Some statements cannot be rolled back. In general, these include data definition language (DDL) statements, such as those that create or drop databases, or those that create, drop, or alter tables.
You may wish to design your transactions not to include such statements.
If you issue a statement that cannot be rolled back early in a transaction,
and then another statement later fails, the full effect of the transaction
cannot be rolled back by issuing a ROLLBACK
statement.
The following commands implicitly end a transaction (as if you had done
a COMMIT
before executing the command):
Command | Command | Command |
ALTER TABLE | BEGIN | CREATE INDEX
|
DROP DATABASE | DROP INDEX | DROP TABLE
|
LOAD MASTER DATA | LOCK TABLES | RENAME TABLE
|
SET AUTOCOMMIT=1 | START TRANSACTION | TRUNCATE
|
UNLOCK TABLES
also ends a transaction if any tables currently are
locked. Prior to MySQL 4.0.13, CREATE TABLE
ends a transaction if
the binary update log is enabled.
Transactions cannot be nested. This is a consequence of the implicit
COMMIT
performed for any current transaction when you issue a
START TRANSACTION
statement or one of its synonyms.
SAVEPOINT
and ROLLBACK TO SAVEPOINT
Syntax
Starting from MySQL 4.0.14 and 4.1.1, InnoDB
supports the SQL commands
SAVEPOINT
and ROLLBACK TO SAVEPOINT
.
SAVEPOINT identifier
This statement sets a named transaction savepoint whose name is
identifier
. If the current transaction already has a
savepoint with the same name, the old savepoint is deleted and a
new one is set.
ROLLBACK TO SAVEPOINT identifier
This statement rolls back a transaction to the named savepoint.
Modifications that this transaction made to rows after the savepoint
was set are undone in the rollback, but InnoDB
does not
release the row locks that were stored in memory after the savepoint.
(Note that for a new inserted row, the lock information is carried by
the transaction ID stored in the row; the lock is not separately
stored in memory. In this case, the row lock is released in the undo.)
Savepoints that were set at a later time than the named savepoint are
deleted.
If the command returns the following error, it means that no savepoint with the specified name exists:
ERROR 1181: Got error 153 during ROLLBACK
All savepoints of the current transaction are deleted if you execute a
COMMIT
, or a ROLLBACK
that does not name a savepoint.
LOCK TABLES
and UNLOCK TABLES
SyntaxLOCK TABLES tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE} [, tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE} ...] ... UNLOCK TABLES
LOCK TABLES
locks tables for the current thread. UNLOCK
TABLES
releases any locks held by the current thread. All tables that
are locked by the current thread are implicitly unlocked when the
thread issues another LOCK TABLES
, or when the connection to the
server is closed.
To use LOCK TABLES
in MySQL 4.0.2 you need the global
LOCK TABLES
privilege and a SELECT
privilege on the
involved tables. In MySQL 3.23 you need to have SELECT
,
insert
, DELETE
and UPDATE
privileges for the
tables.
The main reasons to use LOCK TABLES
are for emulating transactions
or getting more speed when updating tables. This is explained in more
detail later.
If a thread obtains a READ
lock on a table, that thread (and all other
threads) can only read from the table. If a thread obtains a WRITE
lock on a table, then only the thread holding the lock can read from
or write to the table. Other threads are blocked.
The difference between READ LOCAL
and READ
is that
READ LOCAL
allows non-conflicting INSERT
statements to
execute while the lock is held. This can't however be used if you are
going to manipulate the database files outside MySQL while you
hold the lock.
When you use LOCK TABLES
, you must lock all tables that you are
going to use and you must use the same alias that you are going to use
in your queries! If you are using a table multiple times in a query
(with aliases), you must get a lock for each alias!
WRITE
locks normally have higher priority than READ
locks, to
ensure that updates are processed as soon as possible. This means that if one
thread obtains a READ
lock and then another thread requests a
WRITE
lock, subsequent READ
lock requests will wait until the
WRITE
thread has gotten the lock and released it. You can use
LOW_PRIORITY WRITE
locks to allow other threads to obtain READ
locks while the thread is waiting for the WRITE
lock. You should only
use LOW_PRIORITY WRITE
locks if you are sure that there will
eventually be a time when no threads will have a READ
lock.
LOCK TABLES
works as follows:
This policy ensures that table locking is deadlock free. There is however other things one needs to be aware of with this schema:
If you are using a LOW_PRIORITY WRITE
lock for a table, this
means only that MySQL will wait for this particlar lock until
there is no threads that wants a READ
lock. When the thread has
got the WRITE
lock and is waiting to get the lock for the next
table in the lock table list, all other threads will wait for the
WRITE
lock to be released. If this becomes a serious problem
with your application, you should consider converting some of your
tables to transaction-safe tables.
You can safely kill a thread that is waiting for a table lock with
KILL
. See section 13.5.4.3 KILL
Syntax.
Note that you should not lock any tables that you are using with
INSERT DELAYED
, because in this case the INSERT
is done by a separate thread.
Normally, you don't have to lock tables, as all single UPDATE
statements
are atomic; no other thread can interfere with any other currently executing
SQL statement. There are a few cases when you would like to lock tables
anyway:
READ
-locked table (including the one
holding the lock) and no thread can read a WRITE
-locked table other
than the one holding the lock.
The reason some things are faster under LOCK TABLES
is that
MySQL will not flush the key cache for the locked tables until
UNLOCK TABLES
is called (normally the key cache is flushed after
each SQL statement). This speeds up inserting, updating, or deletes on
MyISAM
tables.
LOCK TABLES
if you want to ensure that
no other thread comes between a SELECT
and an UPDATE
. The
example shown here requires LOCK TABLES
in order to execute safely:
mysql> LOCK TABLES trans READ, customer WRITE; mysql> SELECT SUM(value) FROM trans WHERE customer_id=some_id; mysql> UPDATE customer SET total_value=sum_from_previous_statement -> WHERE customer_id=some_id; mysql> UNLOCK TABLES;Without
LOCK TABLES
, there is a chance that another thread might
insert a new row in the trans
table between execution of the
SELECT
and UPDATE
statements.
By using incremental updates (UPDATE customer SET
value=value+new_value
) or the LAST_INSERT_ID()
function, you can
avoid using LOCK TABLES
in many cases.
You can also solve some cases by using the user-level lock functions
GET_LOCK()
and RELEASE_LOCK()
. These locks are saved in a hash
table in the server and implemented with pthread_mutex_lock()
and
pthread_mutex_unlock()
for high speed.
See section 12.6.4 Miscellaneous Functions.
See section 7.3.1 How MySQL Locks Tables, for more information on locking policy.
You can lock all tables in all databases with read locks with the
FLUSH TABLES WITH READ LOCK
command. See section 13.5.4.2 FLUSH
Syntax. This is very
convenient way to get backups if you have a filesystem, like Veritas,
that can take snapshots in time.
NOTE: LOCK TABLES
is not transaction-safe and will
implicitly commit any active transactions before attempting to lock the
tables.
SET TRANSACTION
SyntaxSET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
Sets the transaction isolation level for the global, whole session or the next transaction.
The default behavior is to set the isolation level for the next (not
started) transaction. If you use the GLOBAL
keyword, the statement
sets the default transaction level globally for all new connections
created from that point on (but not existing connections).
You need the SUPER
privilege to do this. Using the SESSION
keyword sets the
default transaction level for all future transactions performed on the
current connection.
For description of each InnoDB
transaction isolation level, see
section 14.4.9.1 InnoDB and SET ... TRANSACTION ISOLATION LEVEL ...
. InnoDB supports each of these levels
from MySQL 4.0.5 on. The default level is REPEATABLE READ
.
You can set the default global isolation level for mysqld
with
--transaction-isolation=...
. See section 5.2.1 mysqld
Command-line Options.
GRANT
and REVOKE
SyntaxGRANT priv_type [(column_list)] [, priv_type [(column_list)] ...] ON {tbl_name | * | *.* | db_name.*} TO user_name [IDENTIFIED BY [PASSWORD] 'password'] [, user_name [IDENTIFIED BY [PASSWORD] 'password'] ...] [REQUIRE NONE | [{SSL| X509}] [CIPHER cipher [AND]] [ISSUER issuer [AND]] [SUBJECT subject]] [WITH [GRANT OPTION | MAX_QUERIES_PER_HOUR # | MAX_UPDATES_PER_HOUR # | MAX_CONNECTIONS_PER_HOUR #]]
REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...] ON {tbl_name | * | *.* | db_name.*} FROM user_name [, user_name ...] REVOKE ALL PRIVILEGES,GRANT FROM user_name [, user_name ...]
GRANT
and REVOKE
are implemented in MySQL Version 3.22.11 or
later. For earlier MySQL versions, these statements do nothing.
The GRANT
and REVOKE
statements allow system administrators
to create users and grant and revoke rights to MySQL users at
four privilege levels:
mysql.user
table.
GRANT ALL ON *.*
and
REVOKE ALL ON *.*
will grant and revoke only global privileges.
mysql.db
and mysql.host
tables.
GRANT ALL ON db.*
and
REVOKE ALL ON db.*
will grant and revoke only database privileges.
mysql.tables_priv
table.
GRANT ALL ON db.table
and
REVOKE ALL ON db.table
will grant and revoke only table privileges.
mysql.columns_priv
table.
When using REVOKE
you must specify the same columns that were granted.
To make it easy to revoke all privileges for a user, MySQL 4.1.1 has added the syntax:
REVOKE ALL PRIVILEGES,GRANT FROM user_name [, user_name ...]
This will drop all database, table and column level privileges for the user.
For the GRANT
and REVOKE
statements, priv_type
may be
specified as any of the following:
ALL [PRIVILEGES] | Sets all simple privileges except WITH GRANT OPTION
|
ALTER | Allows usage of ALTER TABLE
|
CREATE | Allows usage of CREATE TABLE
|
CREATE TEMPORARY TABLES | Allows usage of CREATE TEMPORARY TABLE
|
DELETE | Allows usage of DELETE
|
DROP | Allows usage of DROP TABLE .
|
EXECUTE | Allows the user to run stored procedures (MySQL 5.0) |
FILE | Allows usage of SELECT ... INTO OUTFILE and LOAD DATA INFILE .
|
INDEX | Allows usage of CREATE INDEX and DROP INDEX
|
INSERT | Allows usage of INSERT
|
LOCK TABLES | Allows usage of LOCK TABLES on tables for which one has the SELECT privilege.
|
PROCESS | Allows usage of SHOW FULL PROCESSLIST
|
REFERENCES | For the future |
RELOAD | Allows usage of FLUSH
|
REPLICATION CLIENT | Gives the right to the user to ask where the slaves/masters are. |
REPLICATION SLAVE | Needed for the replication slaves (to read binlogs from master). |
SELECT | Allows usage of SELECT
|
SHOW DATABASES | SHOW DATABASES shows all databases.
|
SHUTDOWN | Allows usage of mysqladmin shutdown
|
SUPER | Allows one connect (once) even if
max_connections is reached and execute commands CHANGE MASTER ,
KILL thread , mysqladmin debug , PURGE MASTER LOGS and SET GLOBAL
|
UPDATE | Allows usage of UPDATE
|
USAGE | Synonym for ``no privileges.'' |
GRANT OPTION | Synonym for WITH GRANT OPTION
|
USAGE
can be used when you want to create a user that has no privileges.
The privileges CREATE TEMPORARY TABLES
, EXECUTE
,
LOCK TABLES
, REPLICATION ...
, SHOW DATABASES
and
SUPER
are new for in version 4.0.2. To use these new privileges
after upgrading to 4.0.2, you have to run the
mysql_fix_privilege_tables
script.
See section 2.5.8 Upgrading the Grant Tables.
In older MySQL versions, the PROCESS
privilege gives the same
rights as the new SUPER
privilege.
To revoke the GRANT
privilege from a user, use a priv_type
value of GRANT OPTION
:
mysql> REVOKE GRANT OPTION ON ... FROM ...;
The only priv_type
values you can specify for a table are SELECT
,
INSERT
, UPDATE
, DELETE
, CREATE
, DROP
,
GRANT OPTION
, INDEX
, and ALTER
.
The only priv_type
values you can specify for a column (that is, when
you use a column_list
clause) are SELECT
, INSERT
, and
UPDATE
.
MySQL allows you to create database level privileges even if the database doesn't exist, to make it easy to prepare for database usage. Currently MySQL does however not allow one to create table level grants if the table doesn't exist. MySQL will not automatically revoke any privileges even if you drop a table or drop a database.
You can set global privileges by using ON *.*
syntax. You can set
database privileges by using ON db_name.*
syntax. If you specify
ON *
and you have a current database, you will set the privileges for
that database. (Warning: if you specify ON *
and you
don't have a current database, you will affect the global privileges!)
Please note: the `_' and `%' wildcards are allowed when
specifying database names in GRANT
statements that grant privileges at
the global or database levels. This means that if you
wish to use for instance a `_' character as part of a database name,
you should specify it as `\_' in the GRANT
command, to prevent
the user from being able to access additional databases matching the
wildcard pattern, for example, GRANT ... ON `foo\_bar`.* TO ...
.
In order to accommodate granting rights to users from arbitrary hosts,
MySQL supports specifying the user_name
value in the form
user@host
. If you want to specify a user
string
containing special characters (such as `-'), or a host
string
containing special characters or wildcard characters (such as `%'), you
can quote the username or hostname (for example, 'test-user'@'test-hostname'
).
You can specify wildcards in the hostname. For example,
user@'%.loc.gov'
applies to user
for any host in the
loc.gov
domain, and user@'144.155.166.%'
applies to user
for any host in the 144.155.166
class C subnet.
The simple form user
is a synonym for user@"%"
.
MySQL doesn't support wildcards in usernames. Anonymous users are
defined by inserting entries with User=''
into the
mysql.user
table or creating an user with an empty name with the
GRANT
command.
Note: if you allow anonymous users to connect to the MySQL
server, you should also grant privileges to all local users as
user@localhost
because otherwise the anonymous user entry for
the local host in the mysql.user
table will be used when the user
tries to log into the MySQL server from the local machine!
You can verify if this applies to you by executing this query:
mysql> SELECT Host,User FROM mysql.user WHERE User='';
For the moment, GRANT
only supports host, table, database, and
column names up to 60 characters long. A username can be up to 16
characters.
The privileges for a table or column are formed from the
logical OR of the privileges at each of the four privilege
levels. For example, if the mysql.user
table specifies that a
user has a global SELECT
privilege, this can't be denied by an
entry at the database, table, or column level.
The privileges for a column can be calculated as follows:
global privileges OR (database privileges AND host privileges) OR table privileges OR column privileges
In most cases, you grant rights to a user at only one of the privilege levels, so life isn't normally as complicated as above. The details of the privilege-checking procedure are presented in section 5.3 General Security Issues and the MySQL Access Privilege System.
If you grant privileges for a user/hostname combination that does not exist
in the mysql.user
table, an entry is added and remains there until
deleted with a DELETE
command. In other words, GRANT
may
create user
table entries, but REVOKE
will not remove them;
you must do that explicitly using DELETE
.
In MySQL Version 3.22.12 or later,
if a new user is created or if you have global grant privileges, the user's
password will be set to the password specified by the IDENTIFIED BY
clause, if one is given. If the user already had a password, it is replaced
by the new one.
If you don't want to send the password in clear text you can use the
PASSWORD
option followed by a scrambled password from SQL
function PASSWORD()
or the C API function
make_scrambled_password(char *to, const char *password)
.
Warning: if you create a new user but do not specify an
IDENTIFIED BY
clause, the user has no password. This is insecure.
Passwords can also be set with the SET PASSWORD
command.
See section 7.5.6 SET
Syntax.
If you grant privileges for a database, an entry in the mysql.db
table is created if needed. When all privileges for the database have been
removed with REVOKE
, this entry is deleted.
If a user doesn't have any privileges on a table, the table is not displayed
when the user requests a list of tables (for example, with a SHOW TABLES
statement). The same is true for SHOW DATABASES
.
The WITH GRANT OPTION
clause gives the user the ability to give
to other users any privileges the user has at the specified privilege level.
You should be careful to whom you give the GRANT
privilege, as two
users with different privileges may be able to join privileges!
MAX_QUERIES_PER_HOUR #
, MAX_UPDATES_PER_HOUR #
and
MAX_CONNECTIONS_PER_HOUR #
are new in MySQL version 4.0.2.
These options limit the number of queries/updates and logins the user can
do during one hour. If #
is 0 (default), then this means that there
are no limitations for that user. See section 5.4.6 Limiting user resources.
Note: to specify any of these options for an existing user without adding
other additional privileges, use GRANT USAGE ON *.* ... WITH MAX_...
.
You cannot grant another user a privilege you don't have yourself;
the GRANT
privilege allows you to give away only those privileges
you possess.
Be aware that when you grant a user the GRANT
privilege at a
particular privilege level, any privileges the user already possesses (or
is given in the future!) at that level are also grantable by that user.
Suppose you grant a user the INSERT
privilege on a database. If
you then grant the SELECT
privilege on the database and specify
WITH GRANT OPTION
, the user can give away not only the SELECT
privilege, but also INSERT
. If you then grant the UPDATE
privilege to the user on the database, the user can give away the
INSERT
, SELECT
and UPDATE
.
You should not grant ALTER
privileges to a normal user. If you
do that, the user can try to subvert the privilege system by renaming
tables!
Note that if you are using table or column privileges for even one user, the server examines table and column privileges for all users and this will slow down MySQL a bit.
When mysqld
starts, all privileges are read into memory.
Database, table, and column privileges take effect at once, and
user-level privileges take effect the next time the user connects.
Modifications to the grant tables that you perform using GRANT
or
REVOKE
are noticed by the server immediately.
If you modify the grant tables manually (using INSERT
, UPDATE
,
etc.), you should execute a FLUSH PRIVILEGES
statement or run
mysqladmin flush-privileges
to tell the server to reload the grant
tables.
See section 5.4.2 When Privilege Changes Take Effect.
The biggest differences between the SQL standard and MySQL versions of
GRANT
are:
TRIGGER
or UNDER
privileges.
INSERT
privilege on only some of the
columns in a table, you can execute INSERT
statements on the
table; the columns for which you don't have the INSERT
privilege
will be set to their default values. SQL-99 requires you to have the
INSERT
privilege on all columns.
REVOKE
commands or by manipulating the
MySQL grant tables.
For a description of using REQUIRE
, see section 5.4.9 Using Secure Connections.
ANALYZE TABLE
SyntaxANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name[,tbl_name...]
Analyze and store the key distribution for the table. During the
analysis, the table is locked with a read lock. This works on
MyISAM
and BDB
tables.
This is equivalent to running myisamchk -a
on the table.
MySQL uses the stored key distribution to decide in which order tables should be joined when one does a join on something else than a constant.
The command returns a table with the following columns:
Column | Value |
Table | Table name |
Op | Always analyze
|
Msg_type | One of status , error , info , or warning
|
Msg_text | The message |
You can check the stored key distribution with the SHOW INDEX
command.
See section 13.5.3.1 Retrieving Information about Database, Tables, Columns, and Indexes.
If the table hasn't changed since the last ANALYZE TABLE
command,
the table will not be analyzed again.
Before MySQL 4.1.1, ANALYZE
commands are not written
to the binary log. Since MySQL 4.1.1 they are written to the binary
log unless the optional NO_WRITE_TO_BINLOG
keyword
(or its alias LOCAL
) was used.
BACKUP TABLE
SyntaxBACKUP TABLE tbl_name[,tbl_name...] TO '/path/to/backup/directory'
Note: This statement is deprecated. We are working on a better
replacement for it that will provide online backup capabilities.
In the meantime, the mysqlhotcopy
script can be used instead.
Copies to the backup directory the minimum number of table files needed
to restore the table, after flushing any buffered changes to disk. Currently
works only for MyISAM
tables.
For MyISAM
tables, copies `.frm' (definition) and
`.MYD' (data) files. The index file can be rebuilt from those two.
Before using this command, please see section 5.5.1 Database Backups.
During the backup, a read lock will be held for each table, one at time,
as they are being backed up. If you want to back up several tables as
a snapshot, you must first issue LOCK TABLES
obtaining a read
lock for each table in the group.
The command returns a table with the following columns:
Column | Value |
Table | Table name |
Op | Always backup
|
Msg_type | One of status , error , info , or warning
|
Msg_text | The message |
Note that BACKUP TABLE
is only available in MySQL
version 3.23.25 and later.
CHECK TABLE
SyntaxCHECK TABLE tbl_name[,tbl_name...] [option [option...]] option = QUICK | FAST | MEDIUM | EXTENDED | CHANGED
CHECK TABLE
works only on MyISAM
and InnoDB
tables. On
MyISAM
tables, it's the same thing as running myisamchk
--medium-check table_name
on the table.
If you don't specify any option, MEDIUM
is used.
Checks the table or tables for errors. For MyISAM
tables, the key statistics
are updated. The command returns a table with the following columns:
Column | Value |
Table | Table name |
Op | Always check
|
Msg_type | One of status , error , info , or warning
|
Msg_text | The message |
Note that the statement may produce many rows of information for each checked table.
The last row will be of Msg_type status
and should normally be
OK
.
If you don't get OK
, or Table is already up to
date
you should normally run a repair of the table. See section 5.5.2 Using myisamchk
for Table Maintenance and Crash Recovery. Table is already up to date
means that the storage
manager for the table indicated that there was no need to check the table.
The different check types are as follows:
Type | Meaning |
QUICK | Don't scan the rows to check for incorrect links. |
FAST | Only check tables that haven't been closed properly. |
CHANGED | Only check tables that have been changed since the last check or haven't been closed properly. |
MEDIUM | Scan rows to verify that deleted links are okay. This also calculates a key checksum for the rows and verifies this with a calculated checksum for the keys. |
EXTENDED | Do a full key lookup for all keys for each row. This ensures that the table is 100% consistent, but will take a long time! |
For dynamically sized MyISAM
tables, a started check will always
do a MEDIUM
check. For statically sized rows, we skip the row scan
for QUICK
and FAST
as the rows are very seldom corrupted.
You can combine check options, as in the following example that does a quick check on the table to see whether it was closed properly:
CHECK TABLE test_table FAST QUICK;
Note: that in some cases CHECK TABLE
will change the
table! This happens if the table is marked as 'corrupted' or 'not
closed properly' but CHECK TABLE
didn't find any problems in the
table. In this case, CHECK TABLE
will mark the table as okay.
If a table is corrupted, then it's most likely that the problem is in the indexes and not in the data part. All of the above check types checks the indexes thoroughly and should thus find most errors.
If you just want to check a table that you assume is okay, you should use
no check options or the QUICK
option. The latter should be used
when you are in a hurry and can take the very small risk that
QUICK
didn't find an error in the datafile. (In most cases
MySQL should find, under normal usage, any error in the datafile.
If this happens then the table will be marked as 'corrupted',
in which case the table can't be used until it's repaired.)
FAST
and CHANGED
are mostly intended to be used from a
script (for example to be executed from cron
) if you want to check your
table from time to time. In most cases, FAST
is to be prefered
over CHANGED
. (The only case when it isn't is when you suspect
that you have found a bug in the MyISAM
code.)
EXTENDED
is only to be used after you have run a normal check but
still get strange errors from a table when MySQL tries to
update a row or find a row by key (this is very unlikely if a
normal check has succeeded!).
Some problems reported by CHECK TABLE
can't be corrected automatically:
Found row where the auto_increment column has the value 0
.
This means that you have a row in the table where the
AUTO_INCREMENT
index column contains the value 0.
(It's possible to create a row where the AUTO_INCREMENT
column is 0 by
explicitly setting the column to 0 with an UPDATE
statement.)
This isn't an error in itself, but could cause trouble if you decide to
dump the table and restore it or do an ALTER TABLE
on the
table. In this case, the AUTO_INCREMENT
column will change value,
according to the rules of AUTO_INCREMENT
columns, which could cause
problems such as a duplicate key error.
To get rid of the warning, just execute an UPDATE
statement
to set the column to some other value than 0.
CHECKSUM TABLE
SyntaxCHECKSUM TABLE tbl_name[,tbl_name ...] [ QUICK | EXTENDED ]
Reports a table checksum. If QUICK
is specified, live table
checksum is reported, or NULL
if the table does not support live
checksum. This is very fast. In EXTENDED
mode the whole table is read row by row and the checksum is
calculated. This can be very slow for large tables. By default - with
neither QUICK
nor EXTENDED
- MySQL returns live checksum
if the table support it and scans the table otherwise.
This statement is implemented in MySQL 4.1.1.
OPTIMIZE TABLE
SyntaxOPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name[,tbl_name]...
OPTIMIZE TABLE
should be used if you have deleted a large part of a
table or if you have made many changes to a table with variable-length rows
(tables that have VARCHAR
, BLOB
, or TEXT
columns).
Deleted records are maintained in a linked list and subsequent INSERT
operations reuse old record positions. You can use OPTIMIZE TABLE
to
reclaim the unused space and to defragment the datafile.
In most setups you don't have to run OPTIMIZE TABLE
at all. Even
if you do a lot of updates to variable length rows it's not likely that
you need to do this more than once a month/week and only on certain
tables.
For the moment, OPTIMIZE TABLE
works only on MyISAM
and
BDB
tables. For BDB
tables, OPTIMIZE TABLE
is
currently mapped to ANALYZE TABLE
.
See section 13.5.2.1 ANALYZE TABLE
Syntax.
You can get OPTIMIZE TABLE
to work on other table types by starting
mysqld
with --skip-new
or --safe-mode
, but in this
case OPTIMIZE TABLE
is just mapped to ALTER TABLE
.
OPTIMIZE TABLE
works the following way:
Note that the table is locked during the time OPTIMIZE TABLE
is
running!
Before MySQL 4.1.1, OPTIMIZE
commands are not written
to the binary log. Since MySQL 4.1.1 they are written to the binary
log unless the optional NO_WRITE_TO_BINLOG
keyword
(or its alias LOCAL
) was used.
REPAIR TABLE
SyntaxREPAIR [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name[,tbl_name...] [QUICK] [EXTENDED] [USE_FRM]
REPAIR TABLE
works only on MyISAM
tables and is the same
as running myisamchk -r table_name
on the table.
Normally you should never have to run this command, but if disaster strikes
you are very likely to get back all your data from a MyISAM table with
REPAIR TABLE
. If your tables get corrupted a lot, you should
try to find the reason for it, to eliminate the need to use REPAIR
TABLE
.
See section A.4.1 What To Do If MySQL Keeps Crashing. See section 14.1.3 MyISAM
Table Problems.
REPAIR TABLE
repairs a possibly corrupted table. The command returns a
table with the following columns:
Column | Value |
Table | Table name |
Op | Always repair
|
Msg_type | One of status , error , info , or warning
|
Msg_text | The message |
Note that the statement may produce many rows of information for each repaired
table.
The last one row will be of Msg_type status
and should
normally be OK
.
If you don't get OK
, you should try
repairing the table with myisamchk --safe-recover
, as REPAIR TABLE
does not yet implement all the options of myisamchk
. In the near
future, we will make it more flexible.
If QUICK
is given, REPAIR TABLE
tries to repair
only the index tree.
If you use EXTENDED
, MySQL will create the index row
by row instead of creating one index at a time with sorting; this may be
better than sorting on fixed-length keys if you have long CHAR
keys that compress very well. This type of repair is like that done by
myisamchk --safe-recover
.
As of MySQL
4.0.2, there is a USE_FRM
mode for REPAIR
.
Use it if the `.MYI' file is missing or if its header is corrupted.
In this mode MySQL will recreate the table, using information from the
`.frm' file. This kind of repair cannot be done with myisamchk
.
Warning: If mysqld
dies during a REPAIR TABLE
,
it's essential that you do at once another REPAIR
on the table
before executing any other commands on it. (It's always good
to start by making a backup). In the worst case you can have a new clean
index file without information about the datafile and when the next
command you do may overwrite the datafile. This is not a likely, but
possible scenario.
Before MySQL 4.1.1, REPAIR
commands are not written
to the binary log. Since MySQL 4.1.1 they are written to the binary
log unless the optional NO_WRITE_TO_BINLOG
keyword
(or its alias LOCAL
) was used.
RESTORE TABLE
SyntaxRESTORE TABLE tbl_name[,tbl_name...] FROM '/path/to/backup/directory'
Restores the table or tables from the backup that was made with
BACKUP TABLE
. Existing tables will not be overwritten; if you
try to restore over an existing table, you will get an error. Restoring
will take longer than backing up due to the need to rebuild the index. The
more keys you have, the longer it will take. Just as BACKUP TABLE
,
RESTORE TABLE
currently works only for MyISAM
tables.
The command returns a table with the following columns:
Column | Value |
Table | Table name |
Op | Always restore
|
Msg_type | One of status , error , info , or warning
|
Msg_text | The message |
SHOW
SyntaxSHOW DATABASES [LIKE wild] or SHOW [OPEN] TABLES [FROM db_name] [LIKE wild] or SHOW [FULL] COLUMNS FROM tbl_name [FROM db_name] [LIKE wild] or SHOW INDEX FROM tbl_name [FROM db_name] or SHOW TABLE STATUS [FROM db_name] [LIKE wild] or SHOW STATUS [LIKE wild] or SHOW VARIABLES [LIKE wild] or SHOW [BDB] LOGS or SHOW [FULL] PROCESSLIST or SHOW GRANTS FOR user or SHOW CREATE TABLE table_name or SHOW MASTER STATUS or SHOW MASTER LOGS or SHOW SLAVE STATUS or SHOW WARNINGS [LIMIT row_count] or SHOW ERRORS [LIMIT row_count] or SHOW TABLE TYPES
SHOW
provides information about databases, tables, columns, or
status information about the server. If the LIKE wild
part is
used, the wild
string can be a string that uses the SQL `%'
and `_' wildcard characters.
Note that there are other forms of the SHOW
statement that provide
information about replication master and slave servers. They are described
in section 13.6 Replication Statements.
You can use db_name.tbl_name
as an alternative to the tbl_name
FROM db_name
syntax. These two statements are equivalent:
mysql> SHOW INDEX FROM mytable FROM mydb; mysql> SHOW INDEX FROM mydb.mytable;
SHOW DATABASES
lists the databases on the MySQL server host.
You can also get this list using the mysqlshow
command line tool.
In version 4.0.2 you will only see those databases for which you have some
kind of privilege, if you don't have the global SHOW DATABASES
privilege.
SHOW TABLES
lists the tables in a given database. You can also
get this list using the mysqlshow db_name
command.
Note: if a user doesn't have any privileges for a table, the table
will not show up in the output from SHOW TABLES
or mysqlshow
db_name
.
SHOW OPEN TABLES
lists the tables that are currently open in
the table cache. See section 7.4.8 How MySQL Opens and Closes Tables. The Comment
field tells
how many times the table is cached
and in_use
.
SHOW COLUMNS
lists the columns in a given table. If you specify
the FULL
option, you will also get the privileges you have for
each column. If the column types are different from what you expect them to
be based on a CREATE TABLE
statement, note that MySQL
sometimes changes column types. See section 13.2.5.1 Silent Column Specification Changes.
As of MySQL 4.1, the FULL
keyword also causes any per-column comments
to be displayed.
The DESCRIBE
statement provides information similar to
SHOW COLUMNS
.
See section 13.3.1 DESCRIBE
Syntax (Get Information About Columns).
SHOW FIELDS
is a synonym for SHOW COLUMNS
, and
SHOW KEYS
is a synonym for SHOW INDEX
. You can also
list a table's columns or indexes with mysqlshow db_name tbl_name
or mysqlshow -k db_name tbl_name
.
SHOW INDEX
returns the index information in a format that closely
resembles the SQLStatistics
call in ODBC. The following columns
are returned:
Column | Meaning |
Table | Name of the table. |
Non_unique | 0 if the index can't contain duplicates, 1 if it can. |
Key_name | Name of the index. |
Seq_in_index | Column sequence number in index, starting with 1. |
Column_name | Column name. |
Collation | How the column is sorted in the index.
In MySQL, this can have values
`A' (Ascending) or NULL (Not
sorted).
|
Cardinality | Number of unique values in the index.
This is updated by running
myisamchk -a .
|
Sub_part | Number of indexed characters if the
column is only partly indexed.
NULL if the entire column is indexed.
|
Packed | Indicates how the key is packed. NULL if it is not.
|
Null | Contains YES if the column may contain NULL .
|
Index_type | Index method used. |
Comment | Various remarks. For now, it tells
in MySQL < 4.0.2 whether or not index is FULLTEXT .
|
Note that as the Cardinality
is counted based on statistics
stored as integers, it's not necessarily accurate for small tables.
The Packed
and Comments
columns were added in MySQL 3.23.0.
The Null
and Index_type
columns were added in MySQL 4.0.2.
SHOW TABLE STATUS
SHOW TABLE STATUS [FROM db_name] [LIKE wild]
SHOW TABLE STATUS
(new in Version 3.23) works likes SHOW
TABLE
, but provides a lot of information about each table. You can
also get this list using the mysqlshow --status db_name
command.
The following columns are returned:
Column | Meaning |
Name | Name of the table. |
Type | Type of table. See section 14 MySQL Table Types. |
Row_format | The row storage format (Fixed, Dynamic, or Compressed). |
Rows | Number of rows. |
Avg_row_length | Average row length. |
Data_length | Length of the datafile. |
Max_data_length | Max length of the datafile. For fixed row formats, this is the max number of rows in the table. For dynamic row formats, this is the total number of data bytes that can be stored in the table, given the data pointer size used. |
Index_length | Length of the index file. |
Data_free | Number of allocated but not used bytes. |
Auto_increment | Next autoincrement value. |
Create_time | When the table was created. |
Update_time | When the datafile was last updated. |
Check_time | When the table was last checked. |
Collation | Table's character set and collation. (new 4.1.1) |
Checksum | Live checksum value (if any). (new in 4.1.1) |
Create_options | Extra options used with CREATE TABLE .
|
Comment | The comment used when creating the table (or some information why MySQL couldn't access the table information). |
InnoDB
tables will report the free space in the tablespace
in the table comment.
SHOW STATUS
SHOW STATUS
provides server status information
(like mysqladmin extended-status
). The output resembles that shown
here, though the format and numbers probably differ:
+--------------------------+------------+ | Variable_name | Value | +--------------------------+------------+ | Aborted_clients | 0 | | Aborted_connects | 0 | | Bytes_received | 155372598 | | Bytes_sent | 1176560426 | | Connections | 30023 | | Created_tmp_disk_tables | 0 | | Created_tmp_tables | 8340 | | Created_tmp_files | 60 | | Delayed_insert_threads | 0 | | Delayed_writes | 0 | | Delayed_errors | 0 | | Flush_commands | 1 | | Handler_delete | 462604 | | Handler_read_first | 105881 | | Handler_read_key | 27820558 | | Handler_read_next | 390681754 | | Handler_read_prev | 6022500 | | Handler_read_rnd | 30546748 | | Handler_read_rnd_next | 246216530 | | Handler_update | 16945404 | | Handler_write | 60356676 | | Key_blocks_used | 14955 | | Key_read_requests | 96854827 | | Key_reads | 162040 | | Key_write_requests | 7589728 | | Key_writes | 3813196 | | Max_used_connections | 0 | | Not_flushed_key_blocks | 0 | | Not_flushed_delayed_rows | 0 | | Open_tables | 1 | | Open_files | 2 | | Open_streams | 0 | | Opened_tables | 44600 | | Questions | 2026873 | | Select_full_join | 0 | | Select_full_range_join | 0 | | Select_range | 99646 | | Select_range_check | 0 | | Select_scan | 30802 | | Slave_running | OFF | | Slave_open_temp_tables | 0 | | Slow_launch_threads | 0 | | Slow_queries | 0 | | Sort_merge_passes | 30 | | Sort_range | 500 | | Sort_rows | 30296250 | | Sort_scan | 4650 | | Table_locks_immediate | 1920382 | | Table_locks_waited | 0 | | Threads_cached | 0 | | Threads_created | 30022 | | Threads_connected | 1 | | Threads_running | 1 | | Uptime | 80380 | +--------------------------+------------+
The status variables listed above have the following meaning:
Variable | Meaning |
Aborted_clients | Number of connections aborted because the client died without closing the connection properly. See section A.2.10 Communication Errors / Aborted Connection. |
Aborted_connects | Number of tries to connect to the MySQL server that failed. See section A.2.10 Communication Errors / Aborted Connection. |
Bytes_received | Number of bytes received from all clients. |
Bytes_sent | Number of bytes sent to all clients. |
Com_xxx | Number of times each xxx command has been executed. |
Connections | Number of connection attempts to the MySQL server. |
Created_tmp_disk_tables | Number of implicit temporary tables on disk created while executing statements. |
Created_tmp_tables | Number of implicit temporary tables in memory created while executing statements. |
Created_tmp_files | How many temporary files mysqld has created.
|
Delayed_insert_threads | Number of delayed insert handler threads in use. |
Delayed_writes | Number of rows written with INSERT DELAYED .
|
Delayed_errors | Number of rows written with INSERT DELAYED for which some error occurred (probably duplicate key ).
|
Flush_commands | Number of executed FLUSH commands.
|
Handler_commit | Number of internal COMMIT commands.
|
Handler_delete | Number of times a row was deleted from a table. |
Handler_read_first | Number of times the first entry was read from an index.
If this is high, it suggests that the server is doing a lot of full index scans, for example,
SELECT col1 FROM foo , assuming that col1 is indexed.
|
Handler_read_key | Number of requests to read a row based on a key. If this is high, it is a good indication that your queries and tables are properly indexed. |
Handler_read_next | Number of requests to read next row in key order. This will be incremented if you are querying an index column with a range constraint. This also will be incremented if you are doing an index scan. |
Handler_read_prev | Number of requests to read previous row in key order. This is mainly used to optimize ORDER BY ... DESC .
|
Handler_read_rnd | Number of requests to read a row based on a fixed position. This will be high if you are doing a lot of queries that require sorting of the result. |
Handler_read_rnd_next | Number of requests to read the next row in the datafile. This will be high if you are doing a lot of table scans. Generally this suggests that your tables are not properly indexed or that your queries are not written to take advantage of the indexes you have. |
Handler_rollback | Number of internal ROLLBACK commands.
|
Handler_update | Number of requests to update a row in a table. |
Handler_write | Number of requests to insert a row in a table. |
Key_blocks_used | The number of used blocks in the key cache.
You can use this value to determine how much of the key cache is in use.
See the discussion of key_buffer_size in
section 13.5.3.4 SHOW VARIABLES .
|
Key_read_requests | The number of requests to read a key block from the cache. |
Key_reads | The number of physical reads of a key block from disk. |
Key_write_requests | The number of requests to write a key block to the cache. |
Key_writes | The number of physical writes of a key block to disk. |
Max_used_connections | The maximum number of connections in use simultaneously. |
Not_flushed_key_blocks | Keys blocks in the key cache that has changed but hasn't yet been flushed to disk. |
Not_flushed_delayed_rows | Number of rows waiting to be written in INSERT DELAY queues.
|
Open_tables | Number of tables that are open. |
Open_files | Number of files that are open. |
Open_streams | Number of streams that are open (used mainly for logging). |
Opened_tables | Number of tables that have been opened. |
Rpl_status | Status of failsafe replication. (Not yet in use). |
Select_full_join | Number of joins without keys (If this is not 0, you should carefully check the indexes of your tables). |
Select_full_range_join | Number of joins where we used a range search on reference table. |
Select_range | Number of joins where we used ranges on the first table. (It's normally not critical even if this is big.) |
Select_scan | Number of joins where we did a full scan of the first table. |
Select_range_check | Number of joins without keys where we check for key usage after each row (If this is not 0, you should carefully check the indexes of your tables). |
Questions | Number of queries sent to the server. |
Slave_open_temp_tables | Number of temporary tables currently open by the slave thread |
Slave_running | Is ON if this is a slave that is connected to a master.
|
Slow_launch_threads | Number of threads that have taken more than slow_launch_time to create.
|
Slow_queries | Number of queries that have taken more than long_query_time seconds. See section 5.7.5 The Slow Query Log.
|
Sort_merge_passes | Number of merges passes the sort algoritm have had to do. If this value is large you should consider increasing sort_buffer .
|
Sort_range | Number of sorts that were done with ranges. |
Sort_rows | Number of sorted rows. |
Sort_scan | Number of sorts that were done by scanning the table. |
ssl_xxx | Variables used by SSL; Not yet implemented. |
Table_locks_immediate | Number of times a table lock was acquired immediately. Available after 3.23.33. |
Table_locks_waited | Number of times a table lock could not be acquired immediately and a wait was needed. If this is high, and you have performance problems, you should first optimize your queries, and then either split your table or tables or use replication. Available after 3.23.33. |
Threads_cached | Number of threads in the thread cache. |
Threads_connected | Number of currently open connections. |
Threads_created | Number of threads created to handle connections. |
Threads_running | Number of threads that are not sleeping. |
Uptime | How many seconds the server has been up. |
Some comments about the above:
Opened_tables
is big, then your table_cache
variable is probably too small.
Key_reads
is big, then your key_buffer_size
variable is
probably too small. The cache miss rate can be calculated with
Key_reads
/Key_read_requests
.
Handler_read_rnd
is big, then you probably have a lot of
queries that require MySQL to scan whole tables or you have
joins that don't use keys properly.
Threads_created
is big, you may want to increase the
thread_cache_size
variable. The cache hit rate can be calculated
with Threads_created
/Connections
.
Created_tmp_disk_tables
is big, you may want to increase the
tmp_table_size
variable to get the temporary tables memory-based
instead of disk based.
SHOW VARIABLES
SHOW [GLOBAL | SESSION] VARIABLES [LIKE wild]
SHOW VARIABLES
shows the values of some MySQL system variables.
The options GLOBAL
and SESSION
are new in MySQL 4.0.3.
With GLOBAL
you will get the variables that will be used for new
connections to MySQL. With SESSION
you will get the values that
are in effect for the current connection. If you are not using either
option, SESSION
is used.
If the default values are unsuitable, you can set most of these
variables using command-line options when mysqld
starts up.
See section 5.2.1 mysqld
Command-line Options. It is also possible to change most variables
with the SET
statement.
See section 7.5.6 SET
Syntax.
The output from SHOW VARIABLES
resembles that shown in the
following list, though the format and numbers may differ somewhat.
You can also get this information using the mysqladmin variables
command.
+---------------------------------+------------------------------+ | Variable_name | Value | +---------------------------------+------------------------------| | back_log | 50 | | basedir | /usr/local/mysql | | bdb_cache_size | 8388572 | | bdb_log_buffer_size | 32768 | | bdb_home | /usr/local/mysql | | bdb_max_lock | 10000 | | bdb_logdir | | | bdb_shared_data | OFF | | bdb_tmpdir | /tmp/ | | bdb_version | Sleepycat Software: ... | | binlog_cache_size | 32768 | | bulk_insert_buffer_size | 8388608 | | character_set | latin1 | | character_sets | latin1 big5 czech euc_kr | | concurrent_insert | ON | | connect_timeout | 5 | | convert_character_set | | | datadir | /usr/local/mysql/data/ | | delay_key_write | ON | | delayed_insert_limit | 100 | | delayed_insert_timeout | 300 | | delayed_queue_size | 1000 | | flush | OFF | | flush_time | 0 | | ft_boolean_syntax | + -><()~*:""&| | | ft_min_word_len | 4 | | ft_max_word_len | 84 | | ft_query_expansion_limit | 20 | | ft_stopword_file | (built-in) | | have_bdb | YES | | have_innodb | YES | | have_isam | YES | | have_raid | NO | | have_symlink | DISABLED | | have_openssl | YES | | have_query_cache | YES | | init_file | | | innodb_additional_mem_pool_size | 1048576 | | innodb_buffer_pool_size | 8388608 | | innodb_data_file_path | ibdata1:10M:autoextend | | innodb_data_home_dir | | | innodb_file_io_threads | 4 | | innodb_force_recovery | 0 | | innodb_thread_concurrency | 8 | | innodb_flush_log_at_trx_commit | 1 | | innodb_fast_shutdown | ON | | innodb_flush_method | | | innodb_lock_wait_timeout | 50 | | innodb_log_arch_dir | | | innodb_log_archive | OFF | | innodb_log_buffer_size | 1048576 | | innodb_log_file_size | 5242880 | | innodb_log_files_in_group | 2 | | innodb_log_group_home_dir | ./ | | innodb_mirrored_log_groups | 1 | | interactive_timeout | 28800 | | join_buffer_size | 131072 | | key_buffer_size | 16773120 | | key_cache_block_size | 1024 | | key_cache_division_limit | 100 | | key_cache_age_threshold | 300 | | language | /usr/local/mysql/share/... | | large_files_support | ON | | local_infile | ON | | locked_in_memory | OFF | | log | OFF | | log_update | OFF | | log_bin | OFF | | log_slave_updates | OFF | | log_slow_queries | OFF | | log_warnings | OFF | | long_query_time | 10 | | low_priority_updates | OFF | | lower_case_table_names | 0 | | max_allowed_packet | 1047552 | | max_binlog_cache_size | 4294967295 | | max_binlog_size | 1073741824 | | max_connections | 100 | | max_connect_errors | 10 | | max_delayed_threads | 20 | | max_heap_table_size | 16777216 | | max_join_size | 4294967295 | | max_relay_log_size | 0 | | max_sort_length | 1024 | | max_user_connections | 0 | | max_tmp_tables | 32 | | max_write_lock_count | 4294967295 | | myisam_max_extra_sort_file_size | 268435456 | | myisam_repair_threads | 1 | | myisam_max_sort_file_size | 2147483647 | | myisam_recover_options | force | | myisam_sort_buffer_size | 8388608 | | net_buffer_length | 16384 | | net_read_timeout | 30 | | net_retry_count | 10 | | net_write_timeout | 60 | | open_files_limit | 1024 | | pid_file | /usr/local/mysql/name.pid | | port | 3306 | | protocol_version | 10 | | query_cache_limit | 1048576 | | query_cache_size | 0 | | query_cache_type | ON | | read_buffer_size | 131072 | | read_rnd_buffer_size | 262144 | | rpl_recovery_rank | 0 | | safe_show_database | OFF | | server_id | 0 | | slave_net_timeout | 3600 | | skip_external_locking | ON | | skip_networking | OFF | | skip_show_database | OFF | | slow_launch_time | 2 | | socket | /tmp/mysql.sock | | sort_buffer_size | 2097116 | | sql_mode | | | table_cache | 64 | | table_type | MYISAM | | thread_cache_size | 3 | | thread_stack | 131072 | | tx_isolation | READ-COMMITTED | | timezone | EEST | | tmp_table_size | 33554432 | | tmpdir | /tmp/:/mnt/hd2/tmp/ | | version | 4.0.4-beta | | wait_timeout | 28800 | +---------------------------------+------------------------------+
Each option is described here. Values for buffer sizes, lengths, and stack
sizes are given in bytes. You can specify values with a suffix of `K'
or `M' to indicate kilobytes or megabytes. For example, 16M
indicates 16 megabytes. The case of suffix letters does not matter;
16M
and 16m
are equivalent:
ansi_mode
.
Is ON
if mysqld
was started with --ansi
.
See section 1.8.3 Running MySQL in ANSI Mode.
back_log
The number of outstanding connection requests MySQL can have. This
comes into play when the main MySQL thread gets very
many connection requests in a very short time. It then takes some time
(although very little) for the main thread to check the connection and start
a new thread. The back_log
value indicates how many requests can be
stacked during this short time before MySQL momentarily stops
answering new requests. You need to increase this only if you expect a large
number of connections in a short period of time.
In other words, this value is the size of the listen queue for incoming
TCP/IP connections. Your operating system has its own limit on the size
of this queue. The manual page for the Unix listen(2)
system
call should have more details. Check your OS documentation for the
maximum value for this variable. Attempting to set back_log
higher than your operating system limit will be ineffective.
basedir
The value of the --basedir
option.
bdb_cache_size
The buffer that is allocated to cache index and rows for BDB
tables. If you don't use BDB
tables, you should start
mysqld
with --skip-bdb
to not waste memory for this
cache.
bdb_log_buffer_size
The buffer that is allocated to cache index and rows for BDB
tables. If you don't use BDB
tables, you should set this to 0 or
start mysqld
with --skip-bdb
to not waste memory for this
cache.
bdb_home
The base directory for BDB
tables. This should be the same directory
you use for --datadir
.
bdb_max_lock
The maximum number of locks (10,000 by default) you can have active on a
BDB table. You should increase this if you get errors of type bdb:
Lock table is out of available locks
or Got error 12 from ...
when you have do long transactions or when mysqld
has to examine
a lot of rows to calculate the query.
bdb_logdir
The value of the --bdb-logdir
option.
bdb_shared_data
Is ON
if you are using --bdb-shared-data
.
bdb_tmpdir
The value of the --bdb-tmpdir
option.
binlog_cache_size
. The size of the cache to hold the SQL
statements for the binary log during a transaction. If you often use
big, multiple-statement transactions you can increase this to get more
performance. See section 13.4.1 START TRANSACTION
, COMMIT
, and ROLLBACK
Syntax.
bulk_insert_buffer_size
MyISAM uses special tree-like cache to make bulk inserts (that is,
INSERT ... SELECT
, INSERT ... VALUES (...), (...), ...
, and
LOAD DATA INFILE
) faster. This variable limits
the size of the cache tree in bytes per thread. Setting it to 0
will disable this optimization.
Note: this cache is only used when adding data to non-empty table.
Default value is 8 MB.
This option used to be named myisam_bulk_insert_tree_size
.
character_set
The default character set.
character_sets
The supported character sets.
concurrent_inserts
If ON
(the default), MySQL will allow you to use INSERT
on
MyISAM
tables at the same time as you run SELECT
queries
on them. You can turn this option off by starting mysqld
with
--safe
or --skip-new
.
connect_timeout
The number of seconds the mysqld
server is waiting for a connect
packet before responding with Bad handshake
.
datadir
The value of the --datadir
option.
delay_key_write
Option for MyISAM tables. Can have one of the following values:
OFF | All CREATE TABLE ... DELAYED_KEY_WRITE are ignored.
|
ON | (default) MySQL will honor the DELAY_KEY_WRITE option
for CREATE TABLE .
|
ALL | All new opened tables are treated as if they were created with the DELAY_KEY_WRITE option.
|
DELAY_KEY_WRITE
is enabled this means that the key buffer for
tables with this option will not get flushed on every index update, but
only when a table is closed. This will speed up writes on keys a lot,
but you should add automatic checking of all tables with myisamchk
--fast --force
if you use this.
delayed_insert_limit
After inserting delayed_insert_limit
rows, the INSERT
DELAYED
handler will check if there are any SELECT
statements
pending. If so, it allows these to execute before continuing.
delayed_insert_timeout
How long a INSERT DELAYED
thread should wait for INSERT
statements before terminating.
delayed_queue_size
What size queue (in rows) should be allocated for handling INSERT
DELAYED
. If the queue becomes full, any client that does INSERT
DELAYED
will wait until there is room in the queue again.
flush
This is ON
if you have started MySQL with the --flush
option.
flush_time
If this is set to a non-zero value, then every flush_time
seconds all
tables will be closed (to free up resources and sync unflushed data to disk). We
only recommend this option on Windows 9x/Me, or on systems where you have
very little resources.
ft_boolean_syntax
List of operators supported by MATCH ... AGAINST(... IN BOOLEAN MODE)
.
See section 13.7 MySQL Full-text Search.
ft_min_word_len
The minimum length of the word to be included in a FULLTEXT
index.
Note: FULLTEXT
indexes must be rebuilt after changing
this variable. (This option is new for MySQL 4.0.)
ft_max_word_len
The maximum length of the word to be included in a FULLTEXT
index.
Note: FULLTEXT
indexes must be rebuilt after changing
this variable. (This option is new for MySQL 4.0.)
ft_query_expansion_limit
Number of top matches to use for query expansion (in
MATCH ... AGAINST (... WITH QUERY EXPANSION)
.
(This option is new for MySQL 4.1.1)
ft_stopword_file
The file from which to read the list of stopwords for full-text searches.
All the words from the file will be used; comments are not honored.
By default, built-in list of stopwords is used
(as defined in `myisam/ft_static.c').
Setting this parameter to an empty string (""
) will disable
stopword filtering.
Note: FULLTEXT
indexes must be rebuilt after changing
this variable. (This option is new for MySQL 4.0.10)
have_innodb
YES
if mysqld
supports InnoDB tables. DISABLED
if --skip-innodb
is used.
have_bdb
YES
if mysqld
supports Berkeley DB tables. DISABLED
if --skip-bdb
is used.
have_raid
YES
if mysqld
supports the RAID
option.
have_openssl
YES
if mysqld
supports SSL (encryption) on the client/server
protocol.
init_connect
A string to be executed by the server for each client that connects.
The string consists of one or more SQL statements. To specify multiple
statements, separate them by semicolon characters.
This variable was added in MySQL 4.1.2.
For example, each client begins by default with auto-commit mode enabled.
There is no global server variable to specify that auto-commit should be
disabled by default, but init_connect
can be used to achieve the
same effect:
SET GLOBAL init_connect='SET AUTOCOMMIT=0';This variable may also be set on the command line or in an option file. To set the variable as just shown using an option file, include these lines:
[mysqld] init_connect='SET AUTOCOMMIT=0'
init_file
The name of the file specified with the --init-file
option when
you start the server. This is a file of SQL statements you want the
server to execute when it starts.
init_slave
This variable is similar to init_connect
, but is a string to be
executed by a slave server each time the SQL thread starts. The format of
the string is the same as for the init_connect
variable.
This variable was added in MySQL 4.1.2.
interactive_timeout
The number of seconds the server waits for activity on an interactive
connection before closing it. An interactive client is defined as a
client that uses the CLIENT_INTERACTIVE
option to
mysql_real_connect()
. See also wait_timeout
.
join_buffer_size
The size of the buffer that is used for full joins (joins that do not
use indexes). The buffer is allocated one time for each full join
between two tables. Increase this value to get a faster full join when
adding indexes is not possible. (Normally the best way to get fast joins
is to add indexes.)
key_buffer_size
Index blocks are buffered and are shared by all threads.
key_buffer_size
is the size of the buffer used for index blocks.
Increase this to get better index handling (for all reads and multiple
writes) to as much as you can afford; 64M on a 256M machine that mainly
runs MySQL is quite common. If you, however, make this too big
(for instance more than 50% of your total memory) your system may start
to page and become extremely slow. Remember that because MySQL does not
cache data reads, you will have to leave some room for the OS
filesystem cache.
You can check the performance of the key buffer by doing SHOW
STATUS
and examine the variables Key_read_requests
,
Key_reads
, Key_write_requests
, and Key_writes
. The
Key_reads/Key_read_request
ratio should normally be < 0.01.
The Key_write/Key_write_requests
is usually near 1 if you are
using mostly updates/deletes but may be much smaller if you tend to
do updates that affect many at the same time or if you are
using DELAY_KEY_WRITE
. See section 13.5.3 SHOW
Syntax.
To get even more speed when writing many rows at the same time, use
LOCK TABLES
. See section 13.4.5 LOCK TABLES
and UNLOCK TABLES
Syntax.
The fraction of the key buffer in use can be determined using
key_buffer_size
in conjunction with the Key_blocks_used
status variable and the blocksize. Before MySQL 4.1.1, key cache blocks
are 1024 bytes, so the fraction of the key buffer in use is:
(Key_blocks_used * 1024) / key_buffer_sizeFrom 4.1.1 on, the buffer block size is available from the
key_cache_block_size
server variable. The fraction of the buffer
in use is:
(Key_blocks_used * key_cache_block_size) / key_buffer_sizeSee section 7.4.6 The MyISAM Key Cache.
key_cache_age_threshold
This value controls the demotion of buffers from the hot sub-chain of a key
cache to the warm sub-chain.
Lower values cause demotion to happen more quickly.
The minimum value is 100.
The default value is 300.
This variable was added in MySQL 4.1.1.
See section 7.4.6 The MyISAM Key Cache.
key_cache_block_size
The size in bytes of blocks in the key buffer.
The default value is 1024.
This variable was added in MySQL 4.1.1.
See section 7.4.6 The MyISAM Key Cache.
key_cache_division_limit
The division point between the hot and warm sub-chains of the key cache
buffer chain. The value is the percentage of the buffer chain to use for
the warm sub-chain. Allowable values range from 1 to 100.
The default value is 100.
This variable was added in MySQL 4.1.1.
See section 7.4.6 The MyISAM Key Cache.
language
The language used for error messages.
large_file_support
If mysqld
was compiled with options for big file support.
locked_in_memory
If mysqld
was locked in memory with --memlock
log
If logging of all queries is enabled.
log_update
If the update log is enabled.
log_bin
If the binary log is enabled.
log_slave_updates
If the updates from the slave should be logged.
long_query_time
If a query takes longer than this (in seconds), the Slow_queries
counter
will be incremented. If you are using --log-slow-queries
, the query
will be logged to the slow query log file. This value is measured in real
time, not CPU time, so a query that may be under the threshold on a lightly
loaded system may be above the threshold on a heavily loaded one.
See section 5.7.5 The Slow Query Log.
lower_case_table_names
If set to 1 table names are stored in lowercase on disk and table
name comparisons will not be case sensitive.
If set to 2 (new in 4.0.18) then table names will be stored as given but
compared in lower case.
From version 4.0.2, this option also applies to database names.
From 4.1.1 this option also applies to table aliases.
Note that you should NOT set this to 0 if you are running MYSQL on a system
that does not have case sensitive filenames (such as Windows or Mac OS X).
New in 4.0.18: If this value is 0 and the datadir
is not case
sensitive, MySQL will automatically set lower_case_table_names
to 1.
See section 10.2.2 Identifier Case Sensitivity.
max_allowed_packet
The maximum size of one packet. The message buffer is initialized to
net_buffer_length
bytes, but can grow up to max_allowed_packet
bytes when needed. This value by default is small, to catch big (possibly
wrong) packets. You must increase this value if you are using big
BLOB
columns. It should be as big as the biggest BLOB
you want
to use. The protocol limits for max_allowed_packet
is 16M in MySQL
3.23 and 1G in MySQL 4.0.
max_binlog_cache_size
If a multiple-statement transaction requires more than this amount of memory,
one will get the error "Multi-statement transaction required more than
'max_binlog_cache_size' bytes of storage".
max_binlog_size
Available after 3.23.33. If a write to the binary (replication) log exceeds
the given value, rotate the logs. You cannot set it to less than 4096
bytes (1024 in MySQL versions older than 4.0.14),
or more than 1 GB. Default is 1 GB. Note if you are using
transactions: a transaction is written in one chunk to the binary log,
hence it is never split between several binary logs. Therefore, if you
have big transactions, you may see binlogs bigger than
max_binlog_size
. If max_relay_log_size
(available
starting from MySQL 4.0.14) is 0, then max_binlog_size
will
apply to relay logs as well.
max_connections
The number of simultaneous clients allowed. Increasing this value increases
the number of file descriptors that mysqld
requires. See below for
comments on file descriptor limits. See section A.2.6 Too many connections
Error.
max_connect_errors
If there is more than this number of interrupted connections from a host
this host will be blocked from further connections. You can unblock a host
with the command FLUSH HOSTS
.
max_delayed_threads
Don't start more than this number of threads to handle INSERT DELAYED
statements. If you try to insert data into a new table after all INSERT
DELAYED
threads are in use, the row will be inserted as if the
DELAYED
attribute wasn't specified. If you set this to 0, MySQL
will never create a max_delayed thread.
max_heap_table_size
This variable sets the maximum size to which subsequently created HEAP
tables are allowed to grow. The value of the variable is used to calculate
a HEAP
table's MAX_ROWS
value. Setting this variable has no
effect on any existing HEAP
table, unless the table is recreated with
a statement such as CREATE TABLE
or TRUNCATE TABLE
, or altered
with ALTER TABLE
.
max_join_size
Joins that are probably going to read more than max_join_size
records return an error. Set this value if your users tend to perform joins
that lack a WHERE
clause, that take a long time, and that return
millions of rows.
max_relay_log_size
Available starting from 4.0.14. If a write to the relay log (a kind of
log used by replication slaves, see section 6.3 Replication Implementation Details) exceeds the given value, rotate the relay log.
This variable enables you to put different size constraints on relay
logs and binary logs.
However, setting the variable to 0 will make MySQL use
max_binlog_size
for both binary logs and relay logs.
You have to set max_relay_log_size
to 0 or more than 4096,
and less than 1 GB. Default is 0.
max_seeks_for_key
Limit assumed max number of seeks when looking up rows based on a key.
The MySQL optimizer will assume that when searching after matching rows
in a table through scanning a key, we will not cause more than this
number of key seeks independent of the cardinality of the key. By setting
this to a low value (100 ?) you can force MySQL to prefer keys instead
of table scans.
max_sort_length
The number of bytes to use when sorting BLOB
or TEXT
values. Only the first max_sort_length
bytes of each value
are used; the rest are ignored.
max_user_connections
The maximum number of active connections for a single user (0 = no limit).
max_tmp_tables
(This option doesn't yet do anything.)
Maximum number of temporary tables a client can keep open at the same time.
max_write_lock_count
After this many write locks, allow some read locks to run in between.
myisam_recover_options
The value of the --myisam-recover
option.
myisam_sort_buffer_size
The buffer that is allocated when sorting the index when doing a
REPAIR
or when creating indexes with CREATE INDEX
or
ALTER TABLE
.
myisam_max_extra_sort_file_size
.
If the temporary file used for fast index creation would be bigger than
using the key cache by the amount specified here, then prefer the key
cache method. This is mainly used to force long character keys in large
tables to use the slower key cache method to create the index.
Note that this parameter is given in megabytes before 4.0.3 and
in bytes beginning with this version.
myisam_repair_threads
.
If this value is greater than one, MyISAM table indexes during
Repair by sorting
process will be created in parallel -
each index in its own thread. Note: multi-threaded repair
is still alpha quality code.
myisam_max_sort_file_size
The maximum size of the temporary file MySQL is allowed to use
while recreating the index (during REPAIR
, ALTER TABLE
or LOAD DATA INFILE
. If the file-size would be bigger than this,
the index will be created through the key cache (which is slower).
Note that this parameter is given in megabytes before 4.0.3 and
in bytes beginning with this version.
net_buffer_length
The communication buffer is reset to this size between queries. This
should not normally be changed, but if you have very little memory, you
can set it to the expected size of a query. (That is, the expected length of
SQL statements sent by clients. If statements exceed this length, the buffer
is automatically enlarged, up to max_allowed_packet
bytes.)
net_read_timeout
Number of seconds to wait for more data from a connection before aborting
the read. Note that when we don't expect data from a connection, the timeout
is defined by write_timeout
. See also slave_net_timeout
.
net_retry_count
If a read on a communication port is interrupted, retry this many times
before giving up. This value should be quite high on FreeBSD
as
internal interrupts are sent to all threads.
net_write_timeout
Number of seconds to wait for a block to be written to a connection before
aborting the write.
open_files_limit
Number of files the system allows mysqld to open. This is the real
value given for the system and may be different from the value you
gave mysqld as a startup parameter. This is 0 on systems where MySQL
can't change the number of open files.
pid_file
The value of the --pid-file
option.
port
The value of the --port
option.
protocol_version
The protocol version used by the MySQL server.
query_alloc_block_size
Size of memory allocation blocks that are allocated for objects
created during query parsing and execution. If you have problem with
memory fragmentation, it may help to increase this a bit.
This variable was added in MySQL 4.0.16.
query_cache_limit
Don't cache results that are bigger than this. (Default 1M).
query_cache_size
The memory allocated to store results from old queries.
If this is 0, the query cache is disabled (default).
query_cache_type
This may be set (only numeric) to
Value | Alias | Comment |
0 | OFF | Don't cache or retrieve results. |
1 | ON | Cache all results except SELECT SQL_NO_CACHE ... queries.
|
2 | DEMAND | Cache only SELECT SQL_CACHE ... queries.
|
query_prealloc_size
Size of the persistent buffer used for query parsing and execution.
This buffer is not freed between queries.
If you are running complex queries, a larger query_prealloc_size
value
may be helpful in improving performance, because it can reduce the need for
the server to perform memory allocation during query execution operations.
This variable was added in MySQL 4.0.16.
range_alloc_block_size
The size of blocks that are allocated when doing range optimization.
This variable was added in MySQL 4.0.16.
read_buffer_size
Each thread that does a sequential scan allocates a buffer of this
size for each table it scans. If you do many sequential scans, you may
want to increase this value.
This option used to be named record_buffer
.
read_rnd_buffer_size
When reading rows in sorted order after a sort, the rows are read
through this buffer to avoid a disk seeks. Can improve ORDER BY
by a lot if set to a high value. As this is a thread-specific variable,
one should not set this big globally, but just change this when running
some specific big queries.
This option used to be named record_rnd_buffer
.
safe_show_database
Don't show databases for which the user doesn't have any database or
table privileges. This can improve security if you're concerned about
people being able to see what databases other users have. See also
skip_show_database
.
server_id
The value of the --server-id
option.
skip_locking
Is OFF if mysqld
uses external locking.
skip_networking
Is ON if we only allow local (socket) connections.
skip_show_database
This prevents people from doing SHOW DATABASES
if they don't have
the PROCESS
privilege. This can improve security if you're
concerned about people being able to see what databases other users
have. See also safe_show_database
.
slave_net_timeout
Number of seconds to wait for more data from a master/slave connection
before aborting the read.
slow_launch_time
If creating the thread takes longer than this value (in seconds), the
Slow_launch_threads
counter will be incremented.
socket
The Unix socket used by the server.
sort_buffer_size
Each thread that needs to do a sort allocates a buffer of this
size. Increase this value for faster ORDER BY
or GROUP BY
operations.
See section A.4.4 Where MySQL Stores Temporary Files.
sql_mode
The current SQL mode.
See section 1.8.2 Selecting SQL Modes.
table_cache
The number of open tables for all threads. Increasing this value
increases the number of file descriptors that mysqld
requires.
You can check if you need to increase the table cache by checking the
Opened_tables
variable.
See section 13.5.3.3 SHOW STATUS
.
If this variable
is big and you don't do FLUSH TABLES
a lot (which just forces all
tables to be closed and reopenend), then you should increase the value of this
variable.
For more information about the table cache, see section 7.4.8 How MySQL Opens and Closes Tables.
table_type
The default table type.
thread_cache_size
How many threads we should keep in a cache for reuse. When a
client disconnects, the client's threads are put in the cache if there
aren't more than thread_cache_size
threads from before. All new
threads are first taken from the cache, and only when the cache is empty
is a new thread created. This variable can be increased to improve
performance if you have a lot of new connections. (Normally this doesn't
give a notable performance improvement if you have a good
thread implementation.) By examing the difference between
the Connections
and Threads_created
status variables
(see section 13.5.3.3 SHOW STATUS
for details) you can see how efficient
thread cache is.
thread_concurrency
On Solaris, mysqld
will call thr_setconcurrency()
with
this value. thr_setconcurrency()
permits the application to give
the threads system a hint for the desired number of threads that should
be run at the same time.
thread_stack
The stack size for each thread. Many of the limits detected by the
crash-me
test are dependent on this value. The default is
large enough for normal operation. See section 7.1.4 The MySQL Benchmark Suite.
timezone
The time zone for the server. This is set from the TZ
environment
variable when mysqld
is started. This can also be given as a
--timezone
argument to mysqld_safe
. See section A.4.6 Time Zone Problems.
tmp_table_size
If an in-memory temporary table exceeds this size, MySQL
will automatically convert it to an on-disk MyISAM
table.
Increase the value of tmp_table_size
if you do many advanced
GROUP BY
queries and you have lots of memory.
tmpdir
The directory used for temporary files and temporary tables.
Starting from MySQL 4.1, it can be set to a list of paths
separated by colon :
(semicolon ;
on Windows). They
will be used in round-robin fashion. This feature can be used to
spread load between several physical disks.
It is possible to set tmpdir
to point to a memory-based filesystem,
except if the MySQL server is a slave. If it is a slave, it needs some
of its temporary files (for replication of temporary tables or of
LOAD DATA INFILE
) to survive a machine's reboot, so a
memory-based tmpdir
which is cleared when the machine reboots is not
suitable; a disk-based tmpdir
is necessary.
transaction_alloc_block_size
Size of memory allocation blocks that are allocated for storing queries
that are part of a transaction that are to be stored in the binary log
when doing a commit.
This variable was added in MySQL 4.0.16.
transaction_prealloc_size
Persistent buffer for transaction_alloc_blocks
. that are not
freed between queries. By making this ``big enough'' to fit all queries in
a common transaction you can avoid a lot of malloc()
calls.
This variable was added in MySQL 4.0.16.
version
The version number for the server.
wait_timeout
The number of seconds the server waits for activity on a not interactive
connection before closing it.
On thread startup SESSION.WAIT_TIMEOUT
is initialized from
GLOBAL.WAIT_TIMEOUT
or GLOBAL.INTERACTIVE_TIMEOUT
depending
on the type of client (as defined by the CLIENT_INTERACTIVE
connect
option). See also interactive_timeout
.
The manual section that describes tuning MySQL contains some information of how to tune the above variables. See section 7.5.2 Tuning Server Parameters.
SHOW [BDB] LOGS
SHOW LOGS
shows you status information about existing log
files. It currently only displays information about Berkeley DB log
files, so an alias for it (available as of MySQL 4.1.1) is SHOW BDB LOGS
.
File
shows the full path to the log file
Type
shows the type of the log file (BDB
for Berkeley
DB log files)
Status
shows the status of the log file (FREE
if the
file can be removed, or IN USE
if the file is needed by the transaction
subsystem)
SHOW PROCESSLIST
SHOW [FULL] PROCESSLIST
shows you which threads are running.
You can also get this information using the mysqladmin processlist
command. If you have the SUPER
privilege, you can see all
threads. Otherwise, you can see only your own threads.
See section 13.5.4.3 KILL
Syntax.
If you don't use the FULL
option, then only the first 100
characters of each query will be shown.
Starting from 4.0.12, MySQL reports the hostname for TCP/IP connections
in hostname:client_port
format to make it easier to find out which client
is doing what.
This command is very useful if you get the 'too many connections' error
message and want to find out what's going on. MySQL reserves
one extra connection for a client with the SUPER
privilege
to ensure that you should always be able to login and check the system
(assuming you are not giving this privilege to all your users).
Some states commonly seen in mysqladmin processlist
Checking table
The thread is performing [automatic] checking of the table.
Closing tables
Means that the thread is flushing the changed table data to disk and
closing the used tables. This should be a fast operation. If not, then
you should check that you don't have a full disk or that the disk is not
in very heavy use.
Connect Out
Slave connecting to master.
Copying to tmp table on disk
The temporary result set was larger than tmp_table_size
and the
thread is now changing the in memory-based temporary table to a disk
based one to save memory.
Creating tmp table
The thread is creating a temporary table to hold a part of the result for
the query.
deleting from main table
When executing the first part of a multiple-table delete and we are only
deleting from the first table.
deleting from reference tables
When executing the second part of a multiple-table delete and we are deleting
the matched rows from the other tables.
Flushing tables
The thread is executing FLUSH TABLES
and is waiting for all
threads to close their tables.
Killed
Someone has sent a kill to the thread and it should abort next time it
checks the kill flag. The flag is checked in each major loop in MySQL,
but in some cases it may still take a short time for the thread to die.
If the thread is locked by some other thread, the kill will take effect
as soon as the other thread releases its lock.
Sending data
The thread is processing rows for a SELECT
statement and is
also sending data to the client.
Sorting for group
The thread is doing a sort to satisfy a GROUP BY
.
Sorting for order
The thread is doing a sort to satisfy a ORDER BY
.
Opening tables
This simply means that the thread is trying to open a table. This is
should be very fast procedure, unless something prevents opening. For
example an ALTER TABLE
or a LOCK TABLE
can prevent opening
a table until the command is finished.
Removing duplicates
The query was using SELECT DISTINCT
in such a way that MySQL
couldn't optimize that distinct away at an early stage. Because of this
MySQL has to do an extra stage to remove all duplicated rows before
sending the result to the client.
Reopen table
The thread got a lock for the table, but noticed after getting the lock
that the underlying table structure changed. It has freed the lock,
closed the table and is now trying to reopen it.
Repair by sorting
The repair code is using sorting to create indexes.
Repair with keycache
The repair code is using creating keys one by one through the key cache.
This is much slower than Repair by sorting
.
Searching rows for update
The thread is doing a first phase to find all matching rows before
updating them. This has to be done if the UPDATE
is changing
the index that is used to find the involved rows.
Sleeping
The thread is wating for the client to send a new command to it.
System lock
The thread is waiting for getting to get a external system lock for the
table. If you are not using multiple mysqld servers that are accessing
the same tables, you can disable system locks with the
--skip-external-locking
option.
Upgrading lock
The INSERT DELAYED
handler is trying to get a lock for the table
to insert rows.
Updating
The thread is searching for rows to update and updating them.
User Lock
The thread is waiting on a GET_LOCK()
.
Waiting for tables
The thread got a notification that the underlying structure for a table
has changed and it needs to reopen the table to get the new structure.
To be able to reopen the table it must however wait until all other
threads have closed the table in question.
This notification happens if another thread has used FLUSH TABLES
or one of the following commands on the table in question: FLUSH
TABLES table_name
, ALTER TABLE
, RENAME TABLE
,
REPAIR TABLE
, ANALYZE TABLE
or OPTIMIZE TABLE
.
waiting for handler insert
The INSERT DELAYED
handler has processed all inserts and are
waiting to get new ones.
Most states are very quick operations. If threads last in any of these states for many seconds, there may be a problem around that needs to be investigated.
There are some other states that are not mentioned previously, but most of
these are only useful to find bugs in mysqld
.
SHOW GRANTS
SHOW GRANTS FOR user
lists the grant commands that must be issued to
duplicate the grants for a user.
mysql> SHOW GRANTS FOR root@localhost; +---------------------------------------------------------------------+ | Grants for root@localhost | +---------------------------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION | +---------------------------------------------------------------------+
To list grants for the current session, you can find out what user the
session was authenticated as by selecting the value
of the CURRENT_USER()
function (new in version 4.0.6).
Then use that value in the SHOW GRANTS
statement.
See section 12.6.4 Miscellaneous Functions.
SHOW CREATE TABLE
Shows a CREATE TABLE
statement that will create the given table:
mysql> SHOW CREATE TABLE t\G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE t ( id INT(11) default NULL auto_increment, s char(60) default NULL, PRIMARY KEY (id) ) TYPE=MyISAM
SHOW CREATE TABLE
quotes table and column names according to
the value of the SQL_QUOTE_SHOW_CREATE
option.
section 7.5.6 SET
Syntax.
SHOW WARNINGS | ERRORS
SHOW WARNINGS [LIMIT row_count] SHOW ERRORS [LIMIT row_count]
This command is implemented in MySQL 4.1.0.
It shows the errors, warnings and notes that one got for the last command. The errors/warnings are reset for each new command that uses a table.
The MySQL server sends back the total number of warnings and errors you
got for the last commend; This can be retrieved by calling
mysql_warning_count()
.
Up to max_error_count
messages are stored (Global and thread
specific variable).
You can retrieve the number of errors from @error_count
and
warnings from @warning_count
.
SHOW WARNINGS
shows all errors, warnings and notes you got for
the last command while SHOW ERRORS
only shows you the errors.
mysql> DROP TABLE IF EXISTS no_such_table; mysql> SHOW WARNINGS; +-------+------+-------------------------------+ | Level | Code | Message | +-------+------+-------------------------------+ | Note | 1051 | Unknown table 'no_such_table' | +-------+------+-------------------------------+
Note that in MySQL 4.1.0 we have just added the frame work for warnings
and not many MySQL command do yet generate warnings. 4.1.1 supports all
kind of warnings for LOAD DATA INFILE
and DML statements such as
INSERT
, UPDATE
and ALTER
commands.
For example, here is a simple case which produces conversion warnings for a insert statement.
mysql> create table t1(a tinyint NOT NULL, b char(4)); Query OK, 0 rows affected (0.00 sec) mysql> insert into t1 values(10,'mysql'),(NULL,'test'),(300,'open source'); Query OK, 3 rows affected, 4 warnings (0.15 sec) Records: 3 Duplicates: 0 Warnings: 4 mysql> show warnings; +---------+------+---------------------------------------------------------------+ | Level | Code | Message | +---------+------+---------------------------------------------------------------+ | Warning | 1263 | Data truncated for column 'b' at row 1 | | Warning | 1261 | Data truncated, NULL supplied to NOT NULL column 'a' at row 2 | | Warning | 1262 | Data truncated, out of range for column 'a' at row 3 | | Warning | 1263 | Data truncated for column 'b' at row 3 | +---------+------+---------------------------------------------------------------+ 4 rows in set (0.00 sec)
Maximum number of warnings can be specified using the server variable
'max_error_count'
, SET max_error_count=[count]
; By default
it is 64. In case to disable warnings, simply reset this variable to
'0'. In case if max_error_count
is 0, then still the warning
count represents how many warnings have occurred, but none of the messages
are stored.
For example, consider the following ALTER
table statement for the
above example, which returns only one warning message even though total
warnings occurred is 3 when you set max_error_count=1.
mysql> show variables like 'max_error_count'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | max_error_count | 64 | +-----------------+-------+ 1 row in set (0.00 sec) mysql> set max_error_count=1; Query OK, 0 rows affected (0.00 sec) mysql> alter table t1 modify b char; Query OK, 3 rows affected, 3 warnings (0.00 sec) Records: 3 Duplicates: 0 Warnings: 3 mysql> show warnings; +---------+------+----------------------------------------+ | Level | Code | Message | +---------+------+----------------------------------------+ | Warning | 1263 | Data truncated for column 'b' at row 1 | +---------+------+----------------------------------------+ 1 row in set (0.00 sec) mysql>
SHOW TABLE TYPES
SHOW TABLE TYPES
This command is implemented in MySQL 4.1.0.
SHOW TABLE TYPES
shows you status information about the table
types. This is particulary useful for checking if a table type is supported;
or to see what is the default table type is.
mysql> SHOW TABLE TYPES; +--------+---------+-----------------------------------------------------------+ | Type | Support | Comment | +--------+---------+-----------------------------------------------------------+ | MyISAM | DEFAULT | Default type from 3.23 with great performance | | HEAP | YES | Hash based, stored in memory, useful for temporary tables | | MERGE | YES | Collection of identical MyISAM tables | | ISAM | YES | Obsolete table type; Is replaced by MyISAM | | InnoDB | YES | Supports transactions, row-level locking and foreign keys | | BDB | NO | Supports transactions and page-level locking | +--------+---------+-----------------------------------------------------------+ 6 rows in set (0.00 sec)
The 'Support' option DEFAULT
indicates whether the particular table
type is supported, and which is the default type. If the server is started with
--default-table-type=InnoDB
, then the InnoDB 'Support' field will
have the value DEFAULT
.
SHOW PRIVILEGES
SHOW PRIVILEGES
This command is implemented in MySQL 4.1.0.
SHOW PRIVILEGES
shows the list of system privileges that the underlying
MySQL server supports.
mysql> show privileges; +------------+------------------------- -+-------------------------------------------------------+ | Privilege | Context | Comment | +------------+--------------------------+-------------------------------------------------------+ | Select | Tables | To retrieve rows from table | | Insert | Tables | To insert data into tables | | Update | Tables | To update existing rows | | Delete | Tables | To delete existing rows | | Index | Tables | To create or drop indexes | | Alter | Tables | To alter the table | | Create | Databases,Tables,Indexes | To create new databases and tables | | Drop | Databases,Tables | To drop databases and tables | | Grant | Databases,Tables | To give to other users those privileges you possess | | References | Databases,Tables | To have references on tables | | Reload | Server Admin | To reload or refresh tables, logs and privileges | | Shutdown | Server Admin | To shutdown the server | | Process | Server Admin | To view the plain text of currently executing queries | | File | File access on server | To read and write files on the server | +------------+--------------------------+-------------------------------------------------------+ 14 rows in set (0.00 sec)
CACHE INDEX
SyntaxCACHE INDEX table_index_list [, table_index_list] ... IN key_cache_name table_index_list: table_name [[INDEX] (index_name[, index_name] ...)]
The CACHE INDEX
statement assigns table indexes to a specific key
cache. It is used only for MyISAM
tables.
The following statement assigns indexes from the tables t1
,
t2
, and t3
to the key cache named hot_cache
:
mysql> CACHE INDEX t1, t2, t3 IN hot_cache; +---------+--------------------+----------+----------+ | Table | Op | Msg_type | Msg_text | +---------+--------------------+----------+----------+ | test.t1 | assign_to_keycache | status | OK | | test.t2 | assign_to_keycache | status | OK | | test.t3 | assign_to_keycache | status | OK | +---------+--------------------+----------+----------+
The syntax of CACHE INDEX
allows you to specify that only particular
indexes from a table should be assigned to the cache. However, the current
implementation assigns all the table's indexes to the cache, so there is no
reason to specify anything other than the table name.
The key cache referred to in a CACHE INDEX
statement can be created
by setting its size with a parameter setting statement or in the server
parameter settings. For example:
mysql> SET GLOBAL keycache1.key_buffer_size=128*1024;
Key cache parameters can be accessed as members of a structured system variable. See section 10.4.2 Structured System Variables.
A key cache must exist before you can assign indexes to it:
mysql> CACHE INDEX t1 in non_existent_cache; ERROR 1283 (HY000): Unknown key cache 'non_existent_cache'
By default, table indexes are assigned to the main (default) key cache created at the server start-up. When a key cache is destroyed, all indexes assigned to it become assigned to the default key cache again.
Index assignment affects the server globally: If one client assigns an index to a given cache, this cache is used for all queries involving the index, no matter what client issues the queries.
CACHE INDEX
was added in MySQL 4.1.1.
FLUSH
SyntaxFLUSH [LOCAL | NO_WRITE_TO_BINLOG] flush_option [,flush_option] ...
You should use the FLUSH
command if you want to clear some of the
internal caches MySQL uses. To execute FLUSH
, you must have
the RELOAD
privilege.
flush_option
can be any of the following:
Option | Description |
HOSTS | Empties the host cache tables. You should flush the
host tables if some of your hosts change IP number or if you get the
error message Host ... is blocked . When more than
max_connect_errors errors occur in a row for a given host while
connection to the MySQL server, MySQL assumes
something is wrong and blocks the host from further connection requests.
Flushing the host tables allows the host to attempt to connect
again. See section A.2.5 Host '...' is blocked Error. You can start mysqld with
-O max_connect_errors=999999999 to avoid this error message.
|
DES_KEY_FILE | Reloads the DES keys from the file that was
specified with the --des-key-file option at server startup time.
|
LOGS | Closes and reopens all log files.
If you have specified an update log file or a binary log file without
an extension, the extension number of the log file will be incremented
by one relative to the previous file. If you have used an extension in
the file name, MySQL will close and reopen the update log file.
See section 5.7.3 The Update Log. This is the same thing as sending the SIGHUP
signal to the mysqld server.
|
PRIVILEGES | Reloads the privileges from the grant tables in
the mysql database.
|
QUERY CACHE | Defragment the query cache to better utilize its
memory. This command will not remove any queries from the cache, unlike
RESET QUERY CACHE .
|
TABLES | Closes all open tables and force all tables in use to be closed. This also flushes the query cache. |
[TABLE | TABLES] tbl_name [,tbl_name...] | Flushes only the given tables. |
TABLES WITH READ LOCK | Closes all open tables and locks all tables for all databases with a read lock until you execute UNLOCK TABLES . This is very convenient way to get backups if you have a filesystem, like Veritas, that can take snapshots in time.
|
STATUS | Resets most status variables to zero. This is something one should only use when debugging a query. See section 1.7.1.3 How to Report Bugs or Problems. |
USER_RESOURCES | Resets all user resources to zero. This will enable blocked users to login again. See section 5.4.6 Limiting user resources. |
Before MySQL 4.1.1, FLUSH
commands are not written
to the binary log. Since MySQL 4.1.1 they are written to the binary
log unless the optional NO_WRITE_TO_BINLOG
keyword
(or its alias LOCAL
) was used, or
unless the command contained one of these arguments: LOGS
,
MASTER
, SLAVE
, TABLES WITH READ LOCK
, because any
of these arguments may cause problems if replicated to a slave.
You can also access some of the commands shown above with the mysqladmin
utility, using the flush-hosts
, flush-logs
, flush-privileges
,
flush-status
or flush-tables
commands.
Take also a look at the RESET
command used with replication.
See section 13.5.4.6 RESET
Syntax.
KILL
SyntaxKILL thread_id KILL CONNECTION thread_id KILL QUERY thread_id
Each connection to mysqld
runs in a separate thread. You can see
which threads are running with the SHOW PROCESSLIST
command and kill
a thread with the KILL thread_id
command.
As of MySQL 5.0.0, KILL
allows the optional CONNECTION
or
QUERY
modifiers:
KILL CONNECTION
is the same as KILL
with no modifier:
It terminates the connection associated with the given thread_id
.
KILL QUERY
terminates the statement that the connection is executing,
but leaves the connection intact.
If you have the PROCESS
privilege, you can see all threads.
If you have the SUPER
privilege, you can kill all threads and
statements. Otherwise, you can only see and kill your own threads and
statements.
You can also use the mysqladmin processlist
and mysqladmin kill
commands to examine and kill threads.
Note: You currently cannot use KILL
with the Embedded MySQL
Server library, because the embedded server merely runs inside the threads
of the host application, it does not create connection threads of its own.
When you do a KILL
, a thread-specific kill flag
is set for
the thread.
In most cases it may take some time for the thread to die, as the kill flag is only checked at specific intervals.
SELECT
, ORDER BY
and GROUP BY
loops, the flag is
checked after reading a block of rows. If the kill flag is set, the
statement is aborted.
ALTER TABLE
the kill flag is checked before each block of
rows are read from the original table. If the kill flag was set the command
is aborted and the temporary table is deleted.
UPDATE
or DELETE
, the kill flag
is checked after each block read and after each updated or deleted
row. If the kill flag is set, the statement is aborted. Note that if you
are not using transactions, the changes will not be rolled back!
GET_LOCK()
will abort with NULL
.
INSERT DELAYED
thread will quickly flush all rows it has in
memory and die.
Locked
),
the table lock will be quickly aborted.
write
call, the
write is aborted with an disk full error message.
LOAD INDEX INTO CACHE
SyntaxLOAD INDEX INTO CACHE table_index_list [, table_index_list] ... table_index_list: table_name [[INDEX] (index_name[, index_name] ...)] [IGNORE LEAVES]
The LOAD INDEX INTO CACHE
statement preloads a table index into the
key cache to which it has been assigned by an explicit CACHE INDEX
statement, or into the default key cache otherwise. LOAD INDEX INTO
CACHE
is used only for MyISAM
tables.
The IGNORE LEAVES
modifier causes only blocks for the non-leaf
nodes of the index to be preloaded.
The following statement preloads nodes (index blocks) of indexes of the
tables t1
and t2
:
mysql> LOAD INDEX INTO CACHE t1, t2 IGNORE LEAVES; +---------+--------------+----------+----------+ | Table | Op | Msg_type | Msg_text | +---------+--------------+----------+----------+ | test.t1 | preload_keys | status | OK | | test.t2 | preload_keys | status | OK | +---------+--------------+----------+----------+
This statement preloads all index blocks from t1
. It preloads only
blocks for the non-leaf nodes from t2
.
The syntax of LOAD INDEX INTO CACHE
allows you to specify that only
particular indexes from a table should be preloaded. However, the current
implementation preloads all the table's indexes into the cache, so there is
no reason to specify anything other than the table name.
LOAD INDEX INTO CACHE
was added in MySQL 4.1.1.
PURGE MASTER LOGS
SyntaxPURGE {MASTER|BINARY} LOGS TO binlog_name PURGE {MASTER|BINARY} LOGS BEFORE date
This statement is used to delete all binary logs strictly prior to the specified binlog or date. See section 13.6.1 SQL Statements for Controlling Master Servers.
PURGE BINARY LOGS
is available as a synonym for PURGE MASTER
LOGS
as of MySQL 4.1.1.
RESET
SyntaxRESET reset_option [,reset_option] ...
The RESET
statement is used to clear things. It also acts as a stronger
version of the FLUSH
command. See section 13.5.4.2 FLUSH
Syntax.
To execute RESET
, you must have the RELOAD
privilege.
Option | Description |
MASTER | Deletes all binary logs listed in the index file, resetting the binlog
index file to be empty. Previously named FLUSH MASTER .
See section 13.6.1 SQL Statements for Controlling Master Servers.
|
SLAVE | Makes the slave forget its replication position in the master
binlogs. Previously named FLUSH SLAVE . See section 13.6.2 SQL Statements for Controlling Slave Servers.
|
QUERY CACHE | Removes all query results from the query cache. |
This section describes replication-related SQL statements. One group of statements is used for controlling master servers. The other is used for controlling slave servers.
Replication can be controlled through the SQL interface. This section discusses statements for managing master replication servers. section 13.6.2 SQL Statements for Controlling Slave Servers discusses statements for managing slave servers.
PURGE MASTER LOGS
PURGE {MASTER|BINARY} LOGS TO 'log_name' PURGE {MASTER|BINARY} LOGS BEFORE 'date'
Deletes all the binary logs listed in the log index that are strictly prior to the specified log or date. The logs also are removed from this list recorded in the log index file, so that the given log now becomes the first.
Example:
PURGE MASTER LOGS TO 'mysql-bin.010'; PURGE MASTER LOGS BEFORE '2003-04-02 22:46:26';
The BEFORE
variant is available in MySQL 4.1; its date argument
can be in 'YYYY-MM-DD hh:mm:ss'
format.
MASTER
and BINARY
are synonyms, though BINARY
can be used
only as of MySQL 4.1.1.
If you have an active slave that is currently reading one of the logs you are trying to delete, this command does nothing and fails with an error. However, if you have a dormant slave, and happen to purge one of the logs it wants to read, the slave will be unable to replicate once it comes up. The command is safe to run while slaves are replicating. You do not need to stop them.
You must first check all the slaves with SHOW SLAVE STATUS
to
see which log they are reading, then do a listing of the logs on the
master with SHOW MASTER LOGS
, find the earliest log among all
the slaves (if all the slaves are up to date, this will be the
last log on the list), backup all the logs you are about to delete
(optional) and purge up to the target log.
RESET MASTER
RESET MASTER
Deletes all binary logs listed in the index file, resetting the binlog index file to be empty.
This statement was named FLUSH MASTER
before MySQL 3.23.26.
SET SQL_LOG_BIN
SET SQL_LOG_BIN = {0|1}
Disables or enables binary logging for the current connection
(SQL_LOG_BIN
is a session variable)
if the client connects using an account that has the SUPER
privilege.
The statement is ignored if the client does not have that privilege.
SHOW BINLOG EVENTS
SHOW BINLOG EVENTS [ IN 'log_name' ] [ FROM pos ] [ LIMIT [offset,] row_count ]
Shows the events in the binary log.
If you do not specify 'log_name'
, the first binary log will be displayed.
This statement is available as of MySQL 4.0
SHOW MASTER STATUS
SHOW MASTER STATUS
Provides status information on the binlog of the master.
SHOW MASTER LOGS
SHOW MASTER LOGS
Lists the binary logs on the master. You should use this
command before using PURGE MASTER LOGS
to find out how far you
should go.
SHOW SLAVE HOSTS
SHOW SLAVE HOSTS
Displays a list of slaves currently registered with the master.
Note that slaves not started with the --report-host=slave_name
option will not be visible in that list.
Replication can be controlled through the SQL interface. This section discusses statements for managing slave replication servers. section 13.6.1 SQL Statements for Controlling Master Servers discusses statements for managing master servers.
CHANGE MASTER TO
CHANGE MASTER TO master_def [, master_def] ... master_def = MASTER_HOST = 'host_name' | MASTER_USER = 'user_name' | MASTER_PASSWORD = 'password' | MASTER_PORT = port_num | MASTER_CONNECT_RETRY = count | MASTER_LOG_FILE = 'master_log_name' | MASTER_LOG_POS = master_log_pos | RELAY_LOG_FILE = 'relay_log_name' | RELAY_LOG_POS = relay_log_pos | MASTER_SSL = {0|1} | MASTER_SSL_CA = 'ca_file_name' | MASTER_SSL_CAPATH = 'ca_directory_name' | MASTER_SSL_CERT = 'cert_file_name' | MASTER_SSL_KEY = 'key_file_name' | MASTER_SSL_CIPHER = 'cipher_list'
Changes the parameters that the slave server uses for connecting to and
communicating with the master server.
The possible master_def
values are shown above.
The relay log options
(RELAY_LOG_FILE
and RELAY_LOG_POS
) are available beginning with
MySQL 4.0.
The SSL options
(MASTER_SSL
,
MASTER_SSL_CA
,
MASTER_SSL_CAPATH
,
MASTER_SSL_CERT
,
MASTER_SSL_KEY
,
and
MASTER_SSL_CIPHER
)
are available beginning with MySQL 4.1.1.
You can change these options even on slaves that are compiled without SSL
support. They will be saved to the `master.info' file but ignored until
you use a server that has SSL support enabled.
For example:
mysql> CHANGE MASTER TO -> MASTER_HOST='master2.mycompany.com', -> MASTER_USER='replication', -> MASTER_PASSWORD='bigs3cret', -> MASTER_PORT=3306, -> MASTER_LOG_FILE='master2-bin.001', -> MASTER_LOG_POS=4, -> MASTER_CONNECT_RETRY=10; mysql> CHANGE MASTER TO -> RELAY_LOG_FILE='slave-relay-bin.006', -> RELAY_LOG_POS=4025;
MASTER_USER
, MASTER_PASSWORD
,
MASTER_SSL
, MASTER_SSL_CA
,
MASTER_SSL_CAPATH
, MASTER_SSL_CERT
, MASTER_SSL_KEY
,
and MASTER_SSL_CIPHER
are information for the slave to be able to
connect to its master. If you don't specify some of these
informations, the non-specified informations will keep their old
value. For example, if the password to connect to your MySQL master has
changed, you just need to issue
mysql> STOP SLAVE; -- if replication was running mysql> CHANGE MASTER TO MASTER_PASSWORD='new3cret'; mysql> START SLAVE; -- if you want to restart replication
to tell the slave about the new password; no need to specify the information which did not change (host, port, user etc).
MASTER_HOST
, MASTER_PORT
are the hostname or IP adress of
the master host, and its TCP port. Note that if MASTER_HOST
is
equal to localhost
, then, like in other parts of MySQL, the port
may be ignored (if Unix socket files can be used for example).
If you specify MASTER_HOST
or MASTER_PORT
,
the slave will assume that the master server is different than
before (even if you specify a host or port value value that is
the same as the current value.) In this case, the old values of master
binlog name and position are considered no longer applicable, so if you
do not specify MASTER_LOG_FILE
and MASTER_LOG_POS
in the
command, MASTER_LOG_FILE=''
and MASTER_LOG_POS=4
are
silently appended to it.
MASTER_LOG_FILE
and MASTER_LOG_POS
are the coordinates
at which the slave I/O thread should begin reading from the master the
next time the thread starts.
If you specify any of them, you can't specify RELAY_LOG_FILE
or
RELAY_LOG_POS
.
If none of MASTER_LOG_FILE
and MASTER_LOG_POS
was
specified, then the last coordinates of the slave SQL thread
before CHANGE MASTER
was issued, are used. This ensures that
replication has no discontinuity, even if the slave SQL thread was late
compared to the slave I/O thread, when you just want to change, say, the
password to use. This safe behavior was introduced starting from MySQL
4.0.17 and 4.1.1. (Before these versions, the used coordinates were
the last coordinates of the slave I/O thread before CHANGE MASTER
was issued, which caused the SQL thread to sometimes lose some events
from the master, thus breaking replication.)
CHANGE MASTER
deletes all relay logs (and starts
a new one), unless you specified RELAY_LOG_FILE
or
RELAY_LOG_POS
(in that case relay logs will be kept;
since MySQL 4.1.1 the RELAY_LOG_PURGE
global variable
will silently be set to 0).
CHANGE MASTER TO
updates `master.info' and
`relay-log.info'.
CHANGE MASTER
is useful for setting up a slave when you have the snapshot of
the master and have recorded the log and the offset on the master that the
snapshot corresponds to. You can run
CHANGE MASTER TO MASTER_LOG_FILE='log_name_on_master',
MASTER_LOG_POS=log_offset_on_master
on the slave after restoring the
snapshot.
The first example above
(CHANGE MASTER TO MASTER_HOST='master2.mycompany.com' etc
)
changes the master and master's binlog
coordinates. This is when you want the slave to replicate the master.
The second example, less frequently used, is when the slave has relay logs which, for some
reason, you want the slave to execute again; to do this the master
needn't be reachable, you just have to do CHANGE MASTER TO
and start the SQL thread (START SLAVE SQL_THREAD
).
You can even use this out of a replication setup, on a standalone,
slave-of-nobody server, to recover after a crash.
Suppose your server has crashed and you have restored a backup.
You want to replay the server's own binlogs (not relay logs, but regular binary
logs), supposedly named `myhost-bin.*'. First make a backup copy of
these binlogs in some safe place, in case you don't exactly follow the
procedure below and accidentally have the server purge the binlogs.
If using MySQL 4.1.1 or newer, do SET GLOBAL RELAY_LOG_PURGE=0
for additional safety.
Then start the server without log-bin
, with a new
(different from before) server ID, with relay-log=myhost-bin
(to make the server believe that these regular binlogs are relay
logs) and skip-slave-start
,
then issue these statements:
mysql> CHANGE MASTER TO -> RELAY_LOG_FILE='myhost-bin.153', -> RELAY_LOG_POS=410, -> MASTER_HOST='some_dummy_string'; mysql> START SLAVE SQL_THREAD;
Then the server will read and execute its own binlogs, thus achieving
crash recovery.
Once the recovery is finished, run STOP SLAVE
, shutdown the
server, delete `master.info' and `relay-log.info',
and restart the server with its original options.
For the moment, specifying MASTER_HOST
(even with a dummy value) is compulsory
to make the server think it is a slave, and giving the server a new,
different from before, server ID is also compulsory otherwise the
server will see events with its ID and think it is in a circular
replication setup and skip the events, which is unwanted. In the
future we plan to add options to get rid of these small constraints.
LOAD DATA FROM MASTER
LOAD DATA FROM MASTER
Takes a snapshot of the master and copies it to the slave.
Updates the values of MASTER_LOG_FILE
and
MASTER_LOG_POS
so that the slave will start replicating from the
correct position. Will honor table and database exclusion rules
specified with replicate-*
options.
Use of this statement is subject to the following conditions:
MyISAM
tables.
In the future, it is planned to make this statement work with
InnoDB
tables and to remove the need for global read lock by using
the non-blocking online backup feature.
If you are loading big tables, you may have to increase the values
of net_read_timeout
and net_write_timeout
on both your master and slave.
See section 13.5.3.4 SHOW VARIABLES
.
Note that LOAD DATA FROM MASTER
does NOT copy any
tables from the mysql
database. This is to make it easy to have
different users and privileges on the master and the slave.
This statement
requires that the replication account that is used to connect to the master
have RELOAD
and SUPER
privileges on the master,
SELECT
privileges on all master's tables you want to load. All
master's tables on which the user has no SELECT
privilege will
be ignored by LOAD DATA FROM MASTER
; this is because the
master will hide them to the user: LOAD DATA FROM MASTER
calls
SHOW DATABASES
to know the master databases to load, but
SHOW DATABASES
returns only databases on which the user has
some privilege.
See section 13.5.3.1 Retrieving Information about Database, Tables, Columns, and Indexes.
On the slave's side, the user which issues LOAD DATA FROM MASTER
should
have grants to drop and create the involved databases and tables.
LOAD TABLE tbl_name FROM MASTER
LOAD TABLE tbl_name FROM MASTER
Downloads a copy of the table from master to the slave. This statement is
implemented mainly for debugging of LOAD DATA FROM MASTER
.
Requires that the account used for connecting to the master server have
RELOAD
and SUPER
privileges on the master, and
SELECT
on the master table to load.
On the slave's side, the user which issues LOAD TABLE FROM MASTER
should
have grants to drop and create the table.
Please read the timeout notes in the description of LOAD DATA
FROM MASTER
above; they apply here, too. Please also read the
limitations of LOAD DATA FROM MASTER
above, they apply too (for
example, LOAD TABLE FROM MASTER
only works for MyISAM
tables).
MASTER_POS_WAIT()
SELECT MASTER_POS_WAIT('master_log_file', master_log_pos)
This is a function, not a command. It is used to ensure that the slave has reached (read and executed up to) a given position in the master's binlog. See section 12.6.4 Miscellaneous Functions for a full description.
RESET SLAVE
RESET SLAVE
Makes the slave forget its replication position in the master's binlogs.
This statement is meant to be used for a clean start: it
deletes the `master.info' and
`relay-log.info' files, all the relay logs, and starts a new relay log.
Note: All relay logs are deleted, even if they had not been
totally executed by the slave SQL thread.
(This is a condition likely to exist on a replication slave that is
highly loaded, or if you have issued a STOP SLAVE
statement.)
Connection information stored in the `master.info' file is
immediately reset to the values specified in the corresponding startup
options, if they were specified.
This information includes values such as
master host, master port, master user, and master password.
If the slave SQL thread was in the middle of replicating temporary
tables when it was stopped, and RESET SLAVE
is issued, these
replicated temporary tables are deleted on the slave.
This statement was named FLUSH SLAVE
before MySQL 3.23.26.
SET GLOBAL SQL_SLAVE_SKIP_COUNTER
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = n
Skip the next n
events from the master. This is
useful for recovering from replication stops caused by a statement.
This statement is valid only when the slave thread is not running. Otherwise, it produces an error.
Before MySQL 4.0, omit the GLOBAL
keyword from the statement.
SHOW SLAVE STATUS
SHOW SLAVE STATUS
Provides status information on
essential parameters of the slave threads. If you issue this statement using
the
mysql
client, you can use a \G
statement terminator rather than
semicolon to get a more readable vertical layout:
mysql> SHOW SLAVE STATUS\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: localhost Master_User: root Master_Port: 3306 Connect_Retry: 3 Master_Log_File: gbichot-bin.005 Read_Master_Log_Pos: 79 Relay_Log_File: gbichot-relay-bin.005 Relay_Log_Pos: 548 Relay_Master_Log_File: gbichot-bin.005 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 79 Relay_Log_Space: 552 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 8
Depending on your version of MySQL, you may not see all the fields just shown. In particular, several fields are present only as of MySQL 4.1.1.
The fields displayed by SHOW SLAVE STATUS
have the following meanings:
Slave_IO_State
State
column of
the output of SHOW PROCESSLIST
for the slave I/O thread; will
tell you if this thread is trying to connect to the master, waiting
for events from the master, reconnecting to the master, etc. Possible
states are listed in section 6.3 Replication Implementation Details. Looking at
this column is necessary because, for example, the thread can be running
but unsuccessfully trying to connect to the master: only this column
will make you aware of the connection problem.
On the opposite, the state of the SQL thread is not copied, because
things are simpler for this thread: if it's running, there is no
problem; if it's not, you will find the error in the
Last_Error
column (described below).
This field is present beginning with MySQL 4.1.1.
Master_Host
Master_User
Master_Port
Connect_Retry
master-connect-retry
.
Master_Log_File
Read_Master_Log_Pos
Relay_Log_File
Relay_Log_Pos
Relay_Master_Log_File
Slave_IO_Running
Slave_SQL_Running
Replicate_Do_DB, Replicate_Ignore_DB
--replicate-do-db
and --replicate-ignore-db
options, if any
Replicate_Do_Table, Replicate_Ignore_Table, Replicate_Wild_Do_Table, Replicate_Wild_Ignore_Table
--replicate-do-table
,
--replicate-ignore-table
,
--replicate-wild-do-table
,
and
--replicate-wild-ignore_table
options, if any
These fields are present beginning with MySQL 4.1.1.
Last_Errno
Last_Error
Last_Errno: 1051 Last_Error: error 'Unknown table 'z'' on query 'drop table z'The message indicates that the table
z
existed on the master and was dropped there, but it
did not exist on the slave, so DROP TABLE
failed on the slave.
(This might occur if you forgot to copy the table to the
slave when setting up replication.)
The empty string means ``no error''.
If the Last_Error
value is not empty, it will also appear as a
message in the slave's error log.
Skip_Counter
SQL_SLAVE_SKIP_COUNTER
.
Exec_Master_Log_Pos
Relay_Master_Log_File
)
of the last event executed by the SQL thread.
((Relay_Master_Log_File
,Exec_Master_Log_Pos
) in the
master's binlog corresponds to
(Relay_Log_File
,Relay_Log_Pos
)
in the relay log).
Relay_Log_Space
Until_Condition, Until_Log_File, Until_Log_Pos
UNTIL
clause of the START SLAVE
statement.
Until_Condition
has these values:
None
if no UNTIL
clause was specified
Master
if the slave is reading until a given position in the master's
binlogs
Relay
if the slave is reading until a given position in its relay logs
Until_Log_File
and Until_Log_Pos
indicate the log filename and
position values that define the point at which the SQL thread will stop
executing.
These fields are present beginning with MySQL 4.1.1.
Master_SSL_Allowed, Master_SSL_CA_File, Master_SSL_CA_Path, Master_SSL_Cert, Master_SSL_Cipher, Master_SSL_Key
Master_SSL_Allowed
has these values:
Yes
if an SSL connection to the master is allowed
No
if an SSL connection to the master is not allowed
Ignored
if an SSL connection is allowed by the slave server does not
have SSL support enabled
--master-ca
,
--master-capath
,
--master-cert
,
--master-cipher
,
and
--master-key
options.
These fields are present beginning with MySQL 4.1.1.
Seconds_Behind_Master
NULL
when no event has been executed yet, or after CHANGE MASTER
and
RESET SLAVE
. This column can be used to know how ``late'' your slave
is. It will work even though your master and slave don't have identical
clocks.
This field is present beginning with MySQL 4.1.1.
START SLAVE
START SLAVE [thread_name [, thread_name] ... ] START SLAVE [SQL_THREAD] UNTIL MASTER_LOG_FILE = 'log_name', MASTER_LOG_POS = log_pos START SLAVE [SQL_THREAD] UNTIL RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos thread_name = IO_THREAD | SQL_THREAD
START SLAVE
with no options starts both of the slave threads.
The I/O thread reads queries from the master server and stores them in the
relay log. The SQL thread reads the relay log and executes the
queries.
Note that if START SLAVE
succeeds in starting the slave threads it
will return without any error. But even in that case it might be that slave
threads start and then later stop (because they don't manage to
connect to the master or read his binlogs or any other
problem). START SLAVE
will not warn you about this. You must
check your slave's error log for error messages generated by
the slave threads, or check that these are running fine with SHOW
SLAVE STATUS
.
START SLAVE
requires the SUPER
privilege.
As of MySQL 4.0.2, you can add IO_THREAD
or SQL_THREAD
options to the statement to name which of the threads to start.
As of MySQL 4.1.1, an UNTIL
clause may be added to specify that
the slave should start until the SQL thread reaches a given point in
the master binlogs or in the slave relay logs. When the SQL thread reaches
that point, it stops. If the SQL_THREAD
option is specified in the
statement, it starts only the SQL thread. Otherwise, it starts both slave
threads. If the SQL thread is already running, the UNTIL
clause is
ignored and a warning is issued.
With an UNTIL
clause, you must specify both a log filename and
position. Do not mix master and relay log options.
Any UNTIL
condition is reset by a subsequent STOP SLAVE
statement, or a START SLAVE
statement that includes no UNTIL
clause, or a server restart.
The UNTIL
clause can be useful for debugging replication, or to
cause replication to proceed until just before the point where you want
to avoid having the slave replicated a statement. For example, if an unwise
DROP TABLE
statement was executed on the master, you can use
UNTIL
to tell the slave to execute up to that point but no farther.
To find what the event is, use mysqlbinlog
with the master logs or
relay logs, or by using a SHOW BINLOG EVENTS
statement.
If you are using UNTIL
to have the slave process replicated queries in
sections, it is recommended that you start the slave with the
--skip-slave-start
option to prevent the SQL thread from running
when the slave starts. It's probably best to use this option in an option
file rather than on the command line, so that an unexpected server restart does
not cause it to be forgotten.
The SHOW SLAVE STATUS
statement includes output fields that display
the current values of the UNTIL
condition.
This command is called SLAVE START
before MySQL 4.0.5.
For the moment, SLAVE START
is still accepted for backward
compatibility, but is deprecated.
STOP SLAVE
STOP SLAVE [thread_name [, thread_name] ... ] thread_name = IO_THREAD | SQL_THREAD
Stops the slave threads.
STOP SLAVE
requires the SUPER
privilege.
Like START SLAVE
, this statement
may be used with the IO_THREAD
and SQL_THREAD
options to name
the thread or threads to stop.
This command is called SLAVE STOP
before MySQL 4.0.5.
For the moment, SLAVE STOP
is still accepted for backward
compatibility, but is deprecated.
MATCH (col1,col2,...) AGAINST (expr [IN BOOLEAN MODE | WITH QUERY EXPANSION] )
As of Version 3.23.23, MySQL has support for full-text indexing
and searching. Full-text indexes in MySQL are an index of type
FULLTEXT
. FULLTEXT
indexes are used with MyISAM
tables
only and can be created from CHAR
, VARCHAR
,
or TEXT
columns at CREATE TABLE
time or added later with
ALTER TABLE
or CREATE INDEX
. For large datasets, it will be
much faster to load your data into a table that has no FULLTEXT
index, then create the index with ALTER TABLE
(or
CREATE INDEX
). Loading data into a table that already has a
FULLTEXT
index could be significantly slower.
Full-text searching is performed with the MATCH()
function.
mysql> CREATE TABLE articles ( -> id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, -> title VARCHAR(200), -> body TEXT, -> FULLTEXT (title,body) -> ); Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO articles VALUES -> (NULL,'MySQL Tutorial', 'DBMS stands for DataBase ...'), -> (NULL,'How To Use MySQL Efficiently', 'After you went through a ...'), -> (NULL,'Optimizing MySQL','In this tutorial we will show ...'), -> (NULL,'1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), -> (NULL,'MySQL vs. YourSQL', 'In the following database comparison ...'), -> (NULL,'MySQL Security', 'When configured properly, MySQL ...'); Query OK, 6 rows affected (0.00 sec) Records: 6 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM articles -> WHERE MATCH (title,body) AGAINST ('database'); +----+-------------------+------------------------------------------+ | id | title | body | +----+-------------------+------------------------------------------+ | 5 | MySQL vs. YourSQL | In the following database comparison ... | | 1 | MySQL Tutorial | DBMS stands for DataBase ... | +----+-------------------+------------------------------------------+ 2 rows in set (0.00 sec)
The MATCH()
function performs a natural language search for a string
against a text collection (a set of one or more columns included in
a FULLTEXT
index). The search string is given as the argument to
AGAINST()
. The search is performed in case-insensitive fashion.
For every row in the table, MATCH()
returns a relevance value,
that is, a similarity measure between the search string and the text in
that row in the columns named in the MATCH()
list.
When MATCH()
is used in a WHERE
clause (see example above)
the rows returned are automatically sorted with highest relevance first.
Relevance values are non-negative floating-point numbers. Zero relevance
means no similarity. Relevance is computed based on the number of words
in the row, the number of unique words in that row, the total number of
words in the collection, and the number of documents (rows) that contain
a particular word.
It is also possible to perform a boolean mode search. This is explained later in the section.
The preceding example is a basic illustration showing how to use the
MATCH()
function. Rows are returned in order of decreasing
relevance.
The next example shows how to retrieve the relevance values explicitly.
As neither WHERE
nor ORDER BY
clauses are present, returned
rows are not ordered.
mysql> SELECT id,MATCH (title,body) AGAINST ('Tutorial') FROM articles; +----+-----------------------------------------+ | id | MATCH (title,body) AGAINST ('Tutorial') | +----+-----------------------------------------+ | 1 | 0.64840710366884 | | 2 | 0 | | 3 | 0.66266459031789 | | 4 | 0 | | 5 | 0 | | 6 | 0 | +----+-----------------------------------------+ 6 rows in set (0.00 sec)
The following example is more complex. The query returns the relevance
and still sorts the rows in order of decreasing relevance. To achieve
this result, you should specify MATCH()
twice. This will cause no
additional overhead, because the MySQL optimizer will notice that the
two MATCH()
calls are identical and invoke the full-text search
code only once.
mysql> SELECT id, body, MATCH (title,body) AGAINST -> ('Security implications of running MySQL as root') AS score -> FROM articles WHERE MATCH (title,body) AGAINST -> ('Security implications of running MySQL as root'); +----+-------------------------------------+-----------------+ | id | body | score | +----+-------------------------------------+-----------------+ | 4 | 1. Never run mysqld as root. 2. ... | 1.5055546709332 | | 6 | When configured properly, MySQL ... | 1.31140957288 | +----+-------------------------------------+-----------------+ 2 rows in set (0.00 sec)
As of Version 4.1.1, full-text search supports query expansion (in particular, its variant ``blind query expansion''). It is generally useful when a search phrase is too short, which often means that the user is relying on implied knowledge that the full-text search engine usually lacks. For example, a user searching for ``database'' may really mean that ``MySQL'', ``Oracle'', ``DB2'', and ``RDBMS'' all are phrases that should match ``databases'' and should be returned, too. This is implied knowledge. Blind query expansion (also known as automatic relevance feedback) works by performing the search twice, where the search phrase for the second search is the original search phrase concatenated with the few top found documents from the first search. Thus, if one of these documents contained the word ``databases'' and the word ``MySQL'', then the second search will find the documents that contain the word ``MySQL'' but not ``database''. Another example could be searching for books by Georges Simenon about Maigret, when a user is not sure how to spell ``Maigret''. Then, searching for ``Megre and the reluctant witnesses'' will find only ``Maigret and the Reluctant Witnesses'' without query expansion, but all books with the word ``Maigret'' on the second pass of a search with query expansion. Note: because blind query expansion tends to increase noise significantly, by returning non-relevant documents, it's only meaningful to use when a search phrase is rather short.
MySQL uses a very simple parser to split text into words. A ``word'' is any sequence of characters consisting of letters, digits, `'', and `_'. Any ``word'' that is present in the stopword list or is just too short is ignored. The default minimum length of words that will be found by full-text searches is four characters. This can be changed as described in section 13.7.2 Fine-tuning MySQL Full-text Search.
Every correct word in the collection and in the query is weighted according to its significance in the query or collection. This way, a word that is present in many documents will have lower weight (and may even have a zero weight), because it has lower semantic value in this particular collection. Otherwise, if the word is rare, it will receive a higher weight. The weights of the words are then combined to compute the relevance of the row.
Such a technique works best with large collections (in fact, it was carefully tuned this way). For very small tables, word distribution does not reflect adequately their semantic value, and this model may sometimes produce bizarre results.
mysql> SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('MySQL'); Empty set (0.00 sec)
The search for the word MySQL
produces no results in the above
example, because that word is present in more than half the rows. As such,
it is effectively treated as a stopword (that is, a word with zero semantic
value). This is the most desirable behavior -- a natural language query
should not return every second row from a 1 GB table.
A word that matches half of rows in a table is less likely to locate relevant documents. In fact, it will most likely find plenty of irrelevant documents. We all know this happens far too often when we are trying to find something on the Internet with a search engine. It is with this reasoning that such rows have been assigned a low semantic value in this particular dataset.
As of Version 4.0.1, MySQL can also perform boolean full-text searches using
the IN BOOLEAN MODE
modifier.
mysql> SELECT * FROM articles WHERE MATCH (title,body) -> AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE); +----+------------------------------+-------------------------------------+ | id | title | body | +----+------------------------------+-------------------------------------+ | 1 | MySQL Tutorial | DBMS stands for DataBase ... | | 2 | How To Use MySQL Efficiently | After you went through a ... | | 3 | Optimizing MySQL | In this tutorial we will show ... | | 4 | 1001 MySQL Tricks | 1. Never run mysqld as root. 2. ... | | 6 | MySQL Security | When configured properly, MySQL ... | +----+------------------------------+-------------------------------------+
This query retrieved all the rows that contain the word MySQL
(note: the 50% threshold is not used), but that do not contain
the word YourSQL
. Note that a boolean mode search does not
automatically sort rows in order of decreasing relevance. You can
see this from result of the preceding query, where the row with the
highest relevance (the one that contains MySQL
twice) is listed
last, not first. A boolean full-text search can also work even without
a FULLTEXT
index, although it would be slow.
The boolean full-text search capability supports the following operators:
+
-
MATCH() ... AGAINST()
without the IN BOOLEAN
MODE
modifier.
< >
<
operator
decreases the contribution and the >
operator increases it.
See the example below.
( )
~
-
operator.
*
"
"
, matches only
rows that contain this phrase literally, as it was typed.
And here are some examples:
apple banana
+apple +juice
+apple macintosh
+apple -macintosh
+apple +(>turnover <strudel)
apple*
"some words"
MyISAM
tables only.
MATCH()
function must be columns from the
same table that is part of the same FULLTEXT
index, unless the
MATCH()
is IN BOOLEAN MODE
.
FULLTEXT
index must have the same character set.
MATCH()
column list must exactly match the column list in some
FULLTEXT
index definition for the table, unless this MATCH()
is IN BOOLEAN MODE
.
AGAINST()
must be a constant string.
Unfortunately, full-text search has few user-tunable parameters yet, although adding some is very high on the TODO. If you have a MySQL source distribution (see section 2.3 MySQL Installation Using a Source Distribution), you can exert more control over full-text searching behavior.
Note that full-text search was carefully tuned for the best searching effectiveness. Modifying the default behavior will, in most cases, only make the search results worse. Do not alter the MySQL sources unless you know what you are doing!
The full-text variables described in the following list must be set at server startup time. You cannot modify them dynamically while the server is running.
ft_min_word_len
.
See section 13.5.3.4 SHOW VARIABLES
.
(This variable is only available from MySQL version 4.0.)
The default value is four characters.
Change it to the value you prefer, and rebuild your FULLTEXT
indexes.
For example, if you want three-character words to be searchable, you can set
this variable by putting the following lines in an option file:
[mysqld] ft_min_word_len=3Then restart the server and rebuild your
FULLTEXT
indexes.
ft_stopword_file
variable.
See section 13.5.3.4 SHOW VARIABLES
.
Rebuild your FULLTEXT
indexes after modifying the stopword list.
(This variable is only available from MySQL version 4.0.10 and onwards)
#define GWS_IN_USE GWS_PROBTo:
#define GWS_IN_USE GWS_FREQThen recompile MySQL. There is no need to rebuild the indexes in this case. Note: by doing this you severely decrease MySQL's ability to provide adequate relevance values for the
MATCH()
function.
If you really need to search for such common words, it would be better to
search using IN BOOLEAN MODE
instead, which does not observe the 50%
threshold.
ft_boolean_syntax
variable.
See section 13.5.3.4 SHOW VARIABLES
.
Still, this variable is read-only; its value is set in
`myisam/ft_static.c'.
For full-text changes that require you to rebuild your FULLTEXT
indexes,
the easiest way to do so for a MyISAM
table is to use the following
statement, which rebuilds the index file:
mysql> REPAIR TABLE tbl_name QUICK;
FULLTEXT
index faster.
MERGE
tables.
FULLTEXT
in CREATE/ALTER TABLE
).
From version 4.0.1, MySQL server
features a Query Cache
.
When in use, the query cache stores the text of a SELECT
query
together with the corresponding result that was sent to the client.
If an identical query is later received, the server will retrieve
the results from the query cache rather than parsing and executing the
same query again.
NOTE: The query cache does not return stale data. When data is modified, any relevant entries in the query cache are flushed.
The query cache is extremely useful in an environment where (some) tables don't change very often and you have a lot of identical queries. This is a typical situation for many web servers that use a lot of dynamic content.
Below is some performance data for the query cache. (These results were generated by running the MySQL benchmark suite on a Linux Alpha 2 x 500 MHz with 2 GB RAM and a 64 MB query cache):
query_cache_size=0
.
By disabling the query cache code there is no noticeable overhead.
(query cache can be excluded from code with help of configure option
--without-query-cache
)
Queries are compared before parsing, thus
SELECT * FROM tbl_name
and
Select * from tbl_name
are regarded as different queries for query cache, so queries need to be exactly the same (byte for byte) to be seen as identical. In addition, a query may be seen as different if for instance one client is using a new communication protocol format or another character set than another client.
Queries that uses different databases, uses different protocol versions or the uses different default character sets are considered different queries and cached separately.
The cache does work for SELECT SQL_CALC_FOUND_ROWS ...
and
SELECT FOUND_ROWS() ...
type queries because the number of
found rows is also stored in the cache.
If query result was returned from query cache then status variable
Com_select
will not be increased, but Qcache_hits
will be.
See section 13.8.4 Query Cache Status and Maintenance.
If a table changes (INSERT
, UPDATE
, DELETE
,
TRUNCATE
, ALTER
or DROP TABLE|DATABASE
),
then all cached queries that used this table (possibly through a
MRG_MyISAM
table!) become invalid and are removed from the cache.
Transactional InnoDB
tables that have been changed will be invalidated
when a COMMIT
is performed.
In MySQL 4.0, the query cache is disabled inside of transactions (it does
not return results). Beginning with MySQL 4.1.1, the query cache will also
work inside of transactions when using InnoDB
tables (it will use the
table version number to detect if the data is still current or not).
Before MySQL 5.0, a query that begins with a leading comment might be cached, but could not be fetched from the cache. This problem is fixed in MySQL 5.0.
A query cannot be cached if it contains one of the functions:
Function | Function | Function |
User-Defined Functions
| CONNECTION_ID
| FOUND_ROWS
|
GET_LOCK
| RELEASE_LOCK
| LOAD_FILE
|
MASTER_POS_WAIT
| NOW
| SYSDATE
|
CURRENT_TIMESTAMP
| CURDATE
| CURRENT_DATE
|
CURTIME
| CURRENT_TIME
| DATABASE
|
ENCRYPT (with one parameter)
| LAST_INSERT_ID
| RAND
|
UNIX_TIMESTAMP (without parameters)
| USER
| BENCHMARK
|
Nor can a query be cached if it contains user variables,
references the mysql system database,
is of the form SELECT ... IN SHARE MODE
,
SELECT ... INTO OUTFILE ...
,
SELECT ... INTO DUMPFILE ...
or
of the form SELECT * FROM AUTOINCREMENT_FIELD IS NULL
(to retrieve last insert ID - ODBC work around).
However, FOUND_ROWS()
will return the correct value,
even if the preceding query was fetched from the cache.
In case a query does not use any tables, or uses temporary tables, or if the user has a column privilege for any of the involved tables, that query will not be cached.
Before a query is fetched from the query cache, MySQL will check that the user has SELECT privilege to all the involved databases and tables. If this is not the case, the cached result will not be used.
The query cache adds a few MySQL
system variables for
mysqld
which may be set in a configuration file, on the
command-line when starting mysqld
.
query_cache_limit
Don't cache results that are bigger than this. (Default 1M).
query_cache_min_res_unit
This variable is present from version 4.1.
The result of a query (the data that is also sent to the client) is stored
in the query cache during result retrieval. Therefore the data is usually
not handled in one big chunk. The query cache allocates blocks for storing
this data on demand, so when one block is filled, a new block is allocated.
Because memory allocation operation is costly (time wise), the query cache
allocates blocks with a minimum size of query_cache_min_res_unit
.
When a query is executed, the last result block is trimmed to the actual
data size, so that unused memory is freed.
query_cache_min_res_unit
is 4 KB which should
be adequate for most cases.
Qcache_free_blocks
), which can cause the query cache to have to
delete queries from the cache due to lack of memory
(Qcache_lowmem_prunes
)). In this case you should decrease
query_cache_min_res_unit
.
Qcache_total_blocks
and Qcache_queries_in_cache
), you can increase performance by
increasing query_cache_min_res_unit
. However, be careful to not
make it to large (see the previous point).
query_cache_size
The amount of memory (specified in bytes) allocated to store results from
old queries. If this is 0, the query cache is disabled (default).
query_cache_type
This may be set (only numeric) to
Option | Description |
0 | (OFF, don't cache or retrieve results) |
1 | (ON, cache all results except SELECT SQL_NO_CACHE ... queries)
|
2 | (DEMAND, cache only SELECT SQL_CACHE ... queries)
|
Inside a thread (connection), the behavior of the query cache can be changed from the default. The syntax is as follows:
QUERY_CACHE_TYPE = OFF | ON | DEMAND
QUERY_CACHE_TYPE = 0 | 1 | 2
Option | Description |
0 or OFF | Don't cache or retrieve results. |
1 or ON | Cache all results except SELECT SQL_NO_CACHE ... queries.
|
2 or DEMAND | Cache only SELECT SQL_CACHE ... queries.
|
SELECT
There are two possible query cache related parameters that may be
specified in a SELECT
query:
Option | Description |
SQL_CACHE
| If QUERY_CACHE_TYPE is DEMAND , allow the query to be cached.
If QUERY_CACHE_TYPE is ON , this is the default.
If QUERY_CACHE_TYPE is OFF , do nothing.
|
SQL_NO_CACHE
| Make this query non-cachable, don't allow this query to be stored in the cache. |
With the FLUSH QUERY CACHE
command you can defragment the query
cache to better utilize its memory. This command will not remove any
queries from the cache.
FLUSH TABLES
also flushes the query cache.
The RESET QUERY CACHE
command removes all query results from the
query cache.
You can check whether the query cache is present in your MySQL version:
mysql> SHOW VARIABLES LIKE 'have_query_cache'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | have_query_cache | YES | +------------------+-------+ 1 row in set (0.00 sec)
You can monitor query cache performance in SHOW STATUS
:
Variable | Description |
Qcache_queries_in_cache
| Number of queries registered in the cache. |
Qcache_inserts
| Number of queries added to the cache. |
Qcache_hits
| Number of cache hits. |
Qcache_lowmem_prunes
| Number of queries that were deleted from cache because of low memory. |
Qcache_not_cached
| Number of non-cached queries
(not cachable, or due to QUERY_CACHE_TYPE ).
|
Qcache_free_memory
| Amount of free memory for query cache. |
Qcache_free_blocks
| Number of free memory blocks in query cache. |
Qcache_total_blocks
| Total number of blocks in query cache. |
Total number of queries =
Qcache_inserts
+ Qcache_hits
+ Qcache_not_cached
.
The query cache uses variable length blocks, so Qcache_total_blocks
and Qcache_free_blocks
may indicate query cache memory fragmentation.
After FLUSH QUERY CACHE
only a single (big) free block remains.
Note: Every query needs a minimum of two blocks (one for the query text and one or more for the query results). Also, every table that is used by a query needs one block, but if two or more queries use same table only one block needs to be allocated.
You can use the Qcache_lowmem_prunes
status variable to tune the query
cache size. It counts the number of queries that have been removed from the
cache to free up memory for caching new queries. The query cache uses a
least recently used
(LRU
) strategy to decide which queries to
remove from the cache.
Go to the first, previous, next, last section, table of contents.