SELECT
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
select_expr [, select_expr] ...
[into_option]
[FROM table_references
[PARTITION partition_list]]
[WHERE where_condition]
[GROUP BY [ {col_name | expr | position}, ... [WITH ROLLUP]
| ROLLUP ({col_name | expr | position}, ...)] ]
[HAVING where_condition]
[WINDOW window_name AS (window_spec)
[, window_name AS (window_spec)] ...]
[ORDER BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[into_option]
[FOR {UPDATE | SHARE}
[OF tbl_name [, tbl_name] ...]
[NOWAIT | SKIP LOCKED]
| LOCK IN SHARE MODE]
[into_option]
into_option: {
INTO OUTFILE 'file_name'
[CHARACTER SET charset_name]
export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name] ...
}
export_options:
[{FIELDS | COLUMNS}
[TERMINATED BY 'string']
[[OPTIONALLY] ENCLOSED BY 'char']
[ESCAPED BY 'char']
]
[LINES
[STARTING BY 'string']
[TERMINATED BY 'string']
]
SELECT 用于检索从一个或多个表中选取的行,可以包含 UNION 操作和子查询。INTERSECT 和 EXCEPT 操作也支持。UNIONINTERSECT,以及 EXCEPT 运算符,在本节后面将有更详细的描述。另见 第 15.2.15 节,“子查询”。SELECT is used to retrieve rows
selected from one or more tables, and can include
UNION operations and subqueries.
INTERSECT and
EXCEPT operations are also
supported. The UNION,
INTERSECT, and EXCEPT
operators are described in more detail later in this section. See
also Section 15.2.15, “Subqueries”.
SELECT 语句可以以 WITH 子句来定义在 SELECT。参见 第 15.2.20 节,“WITH (Common Table Expressions)”。A SELECT statement can start with a
WITH clause to define common table
expressions accessible within the
SELECT. See Section 15.2.20, “WITH (Common Table Expressions)”.
最常见的子句 SELECT 语句如下:The most commonly used clauses of
SELECT statements are these:
每个
select_expr表示您想要检索的列。必须至少有一列select_expr.Eachselect_exprindicates a column that you want to retrieve. There must be at least oneselect_expr.table_references指示要从中检索行的表或表。其语法在第 15.2.13.2 节,“JOIN 子句”.table_referencesindicates the table or tables from which to retrieve rows. Its syntax is described in Section 15.2.13.2, “JOIN Clause”.SELECT支持使用子句通过列出分区或子分区(或两者)来显式选择分区PARTITION位于表名之后的table_reference(见第 15.2.13.2 节,“JOIN 子句”。在这种情况下,仅从列出的分区中选择行,表的任何其他分区将被忽略。有关更多信息和示例,请参见第 26.5 节,“分区选择”.SELECTsupports explicit partition selection using thePARTITIONclause with a list of partitions or subpartitions (or both) following the name of the table in atable_reference(see Section 15.2.13.2, “JOIN Clause”). In this case, rows are selected only from the partitions listed, and any other partitions of the table are ignored. For more information and examples, see Section 26.5, “Partition Selection”.该
WHEREclause, if given, indicates the condition or conditions that rows must satisfy to be selected.where_conditionis an expression that evaluates to true for each row to be selected. The statement selects all rows if there is noWHERE子句创建的表空间。TheWHEREclause, if given, indicates the condition or conditions that rows must satisfy to be selected.where_conditionis an expression that evaluates to true for each row to be selected. The statement selects all rows if there is noWHEREclause.在
WHERE表达式中,你可以使用 MySQL 支持的任何函数和运算符,但聚合(群)函数除外。参见 第 11.5 节“表达式”,以及 第 14 章,函数与运算符。In theWHEREexpression, you can use any of the functions and operators that MySQL supports, except for aggregate (group) functions. See Section 11.5, “Expressions”, and Chapter 14, Functions and Operators.
SELECT 也可以用于检索未引用任何表计算的行。SELECT can also be used to retrieve
rows computed without reference to any table.
例如:For example:
mysql> SELECT 1 + 1;
-> 2
在未引用任何表的情况下,您可以指定 DUAL 作为虚拟表名:
You are permitted to specify DUAL as a dummy
table name in situations where no tables are referenced:
mysql> SELECT 1 + 1 FROM DUAL;
-> 2
DUAL 完全是为了方便那些要求所有 SELECT 语句必须包含 FROM 以及可能的其他子句的人。MySQL 可能会忽略这些子句。如果没有引用任何表,MySQL 并不要求 FROM DUAL。DUAL is purely for the convenience of people
who require that all SELECT
statements should have FROM and possibly other
clauses. MySQL may ignore the clauses. MySQL does not require
FROM DUAL if no tables are referenced.
通常,使用的子句必须按语法描述中显示的顺序给出。例如,HAVING 子句必须在任何 GROUP BY 子句之后并在任何 ORDER
BY 子句之前。INTO 子句(如果存在)可以出现在语法描述指示的任何位置,但在同一条语句中只能出现一次,不能出现在多个位置。有关 INTO 的更多信息,请参见 第 15.2.13.1 节,“SELECT ... INTO 语句”。In general, 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. The INTO clause, if
present, can appear in any position indicated by the syntax
description, but within a given statement can appear only once,
not in multiple positions. For more information about
INTO, see Section 15.2.13.1, “SELECT ... INTO Statement”.
select_expr 列表包含了指示要检索哪些列的选择列表。各项可以指定列或表达式,也可以使用 * 简写:The list of select_expr terms comprises
the select list that indicates which columns to retrieve. Terms
specify a column or expression or can use
*-shorthand:
一个仅包含单个未限定的
*的选择列表可用于简写,以选择所有表的所有列:A select list consisting only of a single unqualified*can be used as shorthand to select all columns from all tables:SELECT * FROM t1 INNER JOIN t2 ...
可作为限定的简写,用于选择指定表的所有列:tbl_name.*can be used as a qualified shorthand to select all columns from the named table:tbl_name.*SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ...
如果表中有不可见列,
*和不包括它们。要包括不可见列,必须显式引用它们。If a table has invisible columns,tbl_name.**anddo not include them. To be included, invisible columns must be referenced explicitly.tbl_name.*在选择列表中将未限定的
*与其他项一起使用可能会导致解析错误。例如:Use of an unqualified*with other items in the select list may produce a parse error. For example:SELECT id, * FROM t1
为避免此问题,请使用限定的
引用:To avoid this problem, use a qualifiedtbl_name.*reference:tbl_name.*SELECT id, t1.* FROM t1
对于选择列表中的每个表,请使用限定的
引用:Use qualifiedtbl_name.*references for each table in the select list:tbl_name.*SELECT AVG(score), t1.* FROM t1 ...
下面的列表提供了关于其他 SELECT 子句的附加信息:The following list provides additional information about other
SELECT clauses:
可以使用
select_expr为AS alias_name指定别名。别名用于表达式的列名,并可用于GROUP BY、ORDER BY或HAVING子句。例如: Aselect_exprcan be given an alias usingAS. The alias is used as the expression's column name and can be used inalias_nameGROUP BY,ORDER BY, orHAVINGclauses. For example:SELECT CONCAT(last_name,', ',first_name) AS full_name FROM mytable ORDER BY full_name;
当为
select_expr使用标识符创建别名时,AS关键字是可选的。前面的例子也可以这样写:TheASkeyword is optional when aliasing aselect_exprwith an identifier. The preceding example could have been written like this:SELECT CONCAT(last_name,', ',first_name) full_name FROM mytable ORDER BY full_name;
然而,由于
AS是可选的,如果在两个select_expr表达式之间忘记了逗号,可能会发生微妙的问题:MySQL 会将第二个解释为别名。例如,在以下语句中,columnb被视为一个别名:However, because theASis optional, a subtle problem can occur if you forget the comma between twoselect_exprexpressions: MySQL interprets the second as an alias name. For example, in the following statement,columnbis treated as an alias name:SELECT columna columnb FROM mytable;
因此,在指定列别名时,习惯明确使用
AS。For this reason, it is good practice to be in the habit of usingASexplicitly when specifying column aliases.在
WHERE,因为执行WHERE。参见 B.3.4.4 节,“列别名问题”。It is not permissible to refer to a column alias in aWHEREclause, because the column value might not yet be determined when theWHEREclause is executed. See Section B.3.4.4, “Problems with Column Aliases”.FROM table_references子句表示要检索行的表。如果你命名多个表,就是在执行连接。有关连接语法的信息,请参见 第 15.2.13.2 节,“JOIN Clause”。对于每个指定的表,你可以选择一个别名。 TheFROMclause indicates the table or 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 15.2.13.2, “JOIN Clause”. For each table specified, you can optionally specify an alias.table_referencestbl_name[[AS]alias] [index_hint]使用索引提示为优化器提供了查询处理过程中如何选择索引的信息。关于指定这些提示的语法描述,请参见 第 10.9.4 节,“索引提示”。The use of index hints provides the optimizer with information about how to choose indexes during query processing. For a description of the syntax for specifying these hints, see Section 10.9.4, “Index Hints”.
您可以使用
SET max_seeks_for_key=作为另一种方法来强制 MySQL 优先使用键扫描而不是表扫描。请参见第 7.1.8 节,“服务器系统变量”.You can usevalueSET max_seeks_for_key=as an alternative way to force MySQL to prefer key scans instead of table scans. See Section 7.1.8, “Server System Variables”.valueYou can refer to a table within the default database as
tbl_name, or asdb_name.tbl_nameto specify a database explicitly. You can refer to a column ascol_name,tbl_name.col_name,或db_name.tbl_name.col_name. You need not specify atbl_name或者db_name.tbl_nameprefix for a column reference unless the reference would be ambiguous. See Section 11.2.2, “Identifier Qualifiers”, for examples of ambiguity that require the more explicit column reference forms.You can refer to a table within the default database astbl_name, or asdb_name.tbl_nameto specify a database explicitly. You can refer to a column ascol_name,tbl_name.col_name, ordb_name.tbl_name.col_name. You need not specify atbl_nameordb_name.tbl_nameprefix for a column reference unless the reference would be ambiguous. See Section 11.2.2, “Identifier Qualifiers”, for examples of ambiguity that require the more explicit column reference forms.A table reference can be aliased using
或者tbl_nameASalias_nametbl_name alias_name. These statements are equivalent: A table reference can be aliased usingortbl_nameASalias_nametbl_name alias_name. These statements are equivalent:SELECT t1.name, t2.salary FROM employee AS t1, info AS t2 WHERE t1.name = t2.name; SELECT t1.name, t2.salary FROM employee t1, info t2 WHERE t1.name = t2.name;
选择输出的列可以用
ORDER BY和GROUP BY子句,使用列名、列别名或列位置来引用。列位置为整数,开头为 1: Columns selected for output can be referred to inORDER BYandGROUP BYclauses using column names, column aliases, or column positions. Column positions are integers and begin with 1:SELECT college, region, seed FROM tournament ORDER BY region, seed; SELECT college, region AS r, seed AS s FROM tournament ORDER BY r, s; SELECT college, region, seed FROM tournament ORDER BY 2, 3;
要逆序排序,在
DESC。默认为升序;这可以通过ASC。To sort in reverse order, add theDESC(descending) keyword to the name of the column in theORDER BYclause that you are sorting by. The default is ascending order; this can be specified explicitly using theASCkeyword.如果
ORDER BY出现在括号中的查询表达式中,并且也应用在外部查询中,结果为未定义,未来 MySQL 版本可能会有所变化。IfORDER BYoccurs within a parenthesized query expression and also is applied in the outer query, the results are undefined and may change in a future version of MySQL.该语法已从 SQL 标准中移除,列位置的使用已被弃用。Use of column positions is deprecated because the syntax has been removed from the SQL standard.
当你使用
ORDER BY或GROUP BY来排序SELECT时,服务器只用系统变量max_sort_length。 When you useORDER BYorGROUP BYto sort a column in aSELECT, the server sorts values using only the initial number of bytes indicated by themax_sort_lengthsystem variable.MySQL 扩展了
GROUP BY的使用,以允许选择未在GROUP BY子句中提及的字段。如果您没有从查询获得预期的结果,请阅读GROUP BY中描述的第 14.19 节,“聚合函数”.MySQL extends the use ofGROUP BYto permit selecting fields that are not mentioned in theGROUP BYclause. If you are not getting the results that you expect from your query, please read the description ofGROUP BYfound in Section 14.19, “Aggregate Functions”.HAVING子句,类似于WHERE子句,指定了选择条件。WHERE子句指定了选择列表中列的条件,但不能引用聚合函数。HAVING子句指定了组的条件,通常由GROUP BY子句构成。查询结果仅包含满足HAVING条件的组。(如果不存在GROUP BY,则所有行隐式构成一个聚合组。)TheHAVINGclause, like theWHEREclause, specifies selection conditions. TheWHEREclause specifies conditions on columns in the select list, but cannot refer to aggregate functions. TheHAVINGclause specifies conditions on groups, typically formed by theGROUP BYclause. The query result includes only groups satisfying theHAVINGconditions. (If noGROUP BYis present, all rows implicitly form a single aggregate group.)HAVING子句几乎是最后应用的,就在发送给客户端的项目之前,且没有优化。(LIMIT是在HAVING的。)TheHAVINGclause is applied nearly last, just before items are sent to the client, with no optimization. (LIMITis applied afterHAVING.)SQL 标准要求
HAVING必须仅引用GROUP BY子句中的列或聚合函数中使用的列。然而,MySQL 支持对此行为的扩展,并允许HAVING引用SELECT列表及外部子查询中的列。The SQL standard requires thatHAVINGmust reference only columns in theGROUP BYclause or columns used in aggregate functions. However, MySQL supports an extension to this behavior, and permitsHAVINGto refer to columns in theSELECTlist and columns in outer subqueries as well.如果
HAVING子句指的是歧义列,则会触发警告。在以下语句中,col2存在歧义,因为它既用作别名,也用作列名:If theHAVINGclause refers to a column that is ambiguous, a warning occurs. In the following statement,col2is ambiguous because it is used as both an alias and a column name:SELECT COUNT(col1) AS col2 FROM t GROUP BY col2 HAVING col2 = 2;
优先考虑标准 SQL 行为,因此如果
HAVING列名同时用于GROUP BY以及作为 select 列列表中的别名列,那么优先考虑GROUP BY列中的列。Preference is given to standard SQL behavior, so if aHAVINGcolumn name is used both inGROUP BYand as an aliased column in the select column list, preference is given to the column in theGROUP BYcolumn.不要使用
HAVING用于应属于WHERE子句中的项。例如,不要写以下内容:Do not useHAVINGfor items that should be in theWHEREclause. For example, do not write the following:SELECT
col_nameFROMtbl_nameHAVINGcol_name> 0;请写这个:Write this instead:
SELECT
col_nameFROMtbl_nameWHEREcol_name> 0;HAVING子句可以指聚合函数,而WHERE子句则不能:TheHAVINGclause can refer to aggregate functions, which theWHEREclause cannot:SELECT user, MAX(salary) FROM users GROUP BY user HAVING MAX(salary) > 10;
(在某些旧版本的 MySQL 中此功能不成立。)(This did not work in some older versions of MySQL.)
MySQL permits duplicate column names. That is, there can be more than one
select_exprwith the same name. This is an extension to standard SQL. Because MySQL also permitsGROUP BY以及HAVINGto refer toselect_exprvalues, this can result in an ambiguity:MySQL permits duplicate column names. That is, there can be more than oneselect_exprwith the same name. This is an extension to standard SQL. Because MySQL also permitsGROUP BYandHAVINGto refer toselect_exprvalues, this can result in an ambiguity:SELECT 12 AS a, a FROM t GROUP BY a;
在该语句中,两个列都具有名称
a。为了确保用于分组的列正确,请为每个列使用不同的名称select_expr.In that statement, both columns have the namea. To ensure that the correct column is used for grouping, use different names for eachselect_expr.WINDOW子句(如存在)定义了可被窗口函数引用的命名窗口。详情请参见 第 14.20.4 节,“Named Windows”。TheWINDOWclause, if present, defines named windows that can be referred to by window functions. For details, see Section 14.20.4, “Named Windows”.MySQL resolves unqualified column or alias references in
ORDER BYclauses by searching in theselect_exprvalues, then in the columns of the tables in theFROMclause. ForGROUP BY或者HAVINGclauses, it searches theFROMclause before searching in theselect_exprvalues. (ForGROUP BY以及HAVING, this differs from the pre-MySQL 5.0 behavior that used the same rules as forORDER BY.)MySQL resolves unqualified column or alias references inORDER BYclauses by searching in theselect_exprvalues, then in the columns of the tables in theFROMclause. ForGROUP BYorHAVINGclauses, it searches theFROMclause before searching in theselect_exprvalues. (ForGROUP BYandHAVING, this differs from the pre-MySQL 5.0 behavior that used the same rules as forORDER BY.)LIMIT子句可用于限制SELECT语句。LIMIT取一或两个数值参数,且两者必须都是非负整数常量,但有以下例外: TheLIMITclause can be used to constrain the number of rows returned by theSELECTstatement.LIMITtakes one or two numeric arguments, which must both be nonnegative integer constants, with these exceptions:在预备语句中,
LIMIT参数可用?。用占位符来指定。Within prepared statements,LIMITparameters can be specified using?placeholder markers.在存储程序中,
LIMIT参数可用整数值例程参数或局部变量指定。Within stored programs,LIMITparameters can be specified using integer-valued routine parameters or local variables.
有两个参数时,第一个参数指定返回第一行的偏移量,第二个参数指定返回的最大行数。初始行的偏移量为 0(而非 1):With two arguments, the first argument specifies the offset of the first row to return, and the second specifies the maximum number of rows to return. The offset of the initial row is 0 (not 1):
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
要检索某一偏移量到结果集末尾的所有行,可以使用较大的数字作为第二个参数。该语句检索从第 96 行到最后一行的所有行:To retrieve all rows from a certain offset up to the end of the result set, you can use some large number for the second parameter. This statement retrieves all rows from the 96th row to the last:
SELECT * FROM tbl LIMIT 95,18446744073709551615;
其中一个参数,值指定从结果集起点返回的行数:With one argument, the value specifies the number of rows to return from the beginning of the result set:
SELECT * FROM tbl LIMIT 5; # Retrieve first 5 rows
换句话说,
LIMIT等同于row_countLIMIT 0,.In other words,row_countLIMITis equivalent torow_countLIMIT 0,.row_count对于预备语句,可以使用占位符。以下语句返回
tbl:For prepared statements, you can use placeholders. The following statements return one row from thetbltable:SET @a=1; PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?'; EXECUTE STMT USING @a;
以下语句返回
tbl:The following statements return the second to sixth rows from thetbltable:SET @skip=1; SET @numrows=5; PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?, ?'; EXECUTE STMT USING @skip, @numrows;
为兼容 PostgreSQL,MySQL 还支持
LIMIT row_count OFFSET offset语法。For compatibility with PostgreSQL, MySQL also supports theLIMITsyntax.row_countOFFSEToffset如果
LIMIT出现在括号中的查询表达式中,并且应用在外部查询中,结果未定义,未来版本的 MySQL 可能会有所变化。IfLIMIToccurs within a parenthesized query expression and also is applied in the outer query, the results are undefined and may change in a future version of MySQL.SELECT ... INTO形式为SELECT允许查询结果写入文件或存储在变量中。更多信息请参见 第 15.2.13.1 节,“SELECT ...INTO 语句”。TheSELECT ... INTOform ofSELECTenables the query result to be written to a file or stored in variables. For more information, see Section 15.2.13.1, “SELECT ... INTO Statement”.如果你在使用页面或行锁的存储引擎中使用
FOR UPDATE,查询检查的行会被写入锁定,直到当前事务结束。 If you useFOR UPDATEwith a storage engine that uses page or row locks, rows examined by the query are write-locked until the end of the current transaction.你不能使用
FOR UPDATE作为SELECT中的一部分,如语句CREATE TABLE。 (如果你尝试这样做,语句会被拒绝并显示错误无法在创建new_tableSELECT ... FROMold_table...old_table时更新表 'new_table' is being created.)You cannot useFOR UPDATEas part of theSELECTin a statement such asCREATE TABLE. (If you attempt to do so, the statement is rejected with the error Can't update table 'new_tableSELECT ... FROMold_table...old_table' while 'new_table' is being created.)FOR SHARE和LOCK IN SHARE MODE设置共享锁,允许其他事务读取检查的行,但不能更新或删除它们。FOR SHARE和LOCK IN SHARE MODE是等价的。然而,FOR SHARE,就像FOR UPDATE一样,支持FOR SHARESKIP LOCKED,以及OF选项。tbl_nameNOWAIT是 SHARE 模式下LOCK IN SHARE MODE,但LOCK IN SHARE MODE仍可向下兼容。FOR SHAREandLOCK IN SHARE MODEset shared locks that permit other transactions to read the examined rows but not to update or delete them.FOR SHAREandLOCK IN SHARE MODEare equivalent. However,FOR SHARE, likeFOR UPDATE, supportsNOWAIT,SKIP LOCKED, andOFoptions.tbl_nameFOR SHAREis a replacement forLOCK IN SHARE MODE, butLOCK IN SHARE MODEremains available for backward compatibility.NOWAIT会立即执行FOR UPDATE或FOR SHARE查询,如果因其他事务持有锁而无法获得行锁,则返回错误。NOWAITcauses aFOR UPDATEorFOR SHAREquery to execute immediately, returning an error if a row lock cannot be obtained due to a lock held by another transaction.SKIP LOCKED会导致FOR UPDATE或FOR SHARE立即执行,排除被其他事务锁定的结果集行。SKIP LOCKEDcauses aFOR UPDATEorFOR SHAREquery to execute immediately, excluding rows from the result set that are locked by another transaction.NOWAIT和SKIP LOCKED选项对基于语句的复制不安全。NOWAITandSKIP LOCKEDoptions are unsafe for statement-based replication.Note跳过锁定行的查询会返回数据视图不一致。
SKIP LOCKED因此不适合一般事务工作。不过,当多个会话访问同一个类似队列的表时,它可以用于避免锁的争夺。Queries that skip locked rows return an inconsistent view of the data.SKIP LOCKEDis therefore not suitable for general transactional work. However, it may be used to avoid lock contention when multiple sessions access the same queue-like table.OFappliestbl_nameFOR UPDATE以及FOR SHAREqueries to named tables. For example:OFappliestbl_nameFOR UPDATEandFOR SHAREqueries to named tables. For example:SELECT * FROM t1, t2 FOR SHARE OF t1 FOR UPDATE OF t2;
当省略
OF时,查询块引用的所有表都会被锁定。因此,在没有tbl_nameOF的情况下使用锁定子句并与另一个锁定子句结合使用会返回错误。在多个锁定子句中指定相同的表也会返回错误。如果在tbl_nameSELECT语句中将别名指定为表名,则锁定子句只能使用该别名。如果SELECT语句未显式指定别名,则锁定子句只能指定实际表名。All tables referenced by the query block are locked whenOFis omitted. Consequently, using a locking clause withouttbl_nameOFin combination with another locking clause returns an error. Specifying the same table in multiple locking clauses returns an error. If an alias is specified as the table name in thetbl_nameSELECTstatement, a locking clause may only use the alias. If theSELECTstatement does not specify an alias explicitly, the locking clause may only specify the actual table name.有关
FOR UPDATE和FOR SHARE的更多信息,请参阅 第 17.7.2.4 节,“锁定读取”。有关NOWAIT和SKIP LOCKED选项的附加信息,请参阅 使用 NOWAIT 和 SKIP LOCKED 的锁定读取并发。For more information aboutFOR UPDATEandFOR SHARE, see Section 17.7.2.4, “Locking Reads”. For additional information aboutNOWAITandSKIP LOCKEDoptions, see Locking Read Concurrency with NOWAIT and SKIP LOCKED.
在 SELECT 关键字之后,你可以使用若干修饰符来影响语句的操作。HIGH_PRIORITY、STRAIGHT_JOIN 以及以 SQL_ 开头的修饰符是 MySQL 对标准 SQL 的扩展。Following the SELECT keyword, you
can use a number of modifiers that affect the operation of the
statement. HIGH_PRIORITY,
STRAIGHT_JOIN, and modifiers beginning with
SQL_ are MySQL extensions to standard SQL.
ALL和DISTINCT修饰符指定是否返回重复行。ALL(默认)表示返回所有匹配行,包括重复行。DISTINCT表示从结果集中去除重复行。两者同时指定会导致错误。DISTINCTROW是DISTINCT的同义词。TheALLandDISTINCTmodifiers specify whether duplicate rows should be returned.ALL(the default) specifies that all matching rows should be returned, including duplicates.DISTINCTspecifies removal of duplicate rows from the result set. It is an error to specify both modifiers.DISTINCTROWis a synonym forDISTINCT.DISTINCT可用于也使用WITH ROLLUP的查询。DISTINCTcan be used with a query that also usesWITH ROLLUP.HIGH_PRIORITY使SELECT的优先级高于更新表的语句。你应仅对非常快速且必须立即执行的查询使用此选项。即使在表被锁定以供读取时,如果有更新语句正在等待表释放,发出的SELECT HIGH_PRIORITY查询仍会执行。这仅影响使用表级锁定的存储引擎(如MyISAM、MEMORY和MERGE)。HIGH_PRIORITYgives theSELECThigher priority than a statement that updates a table. You should use this only for queries that are very fast and must be done at once. ASELECT HIGH_PRIORITYquery that is issued while the table is locked for reading runs even if there is an update statement waiting for the table to be free. This affects only storage engines that use only table-level locking (such asMyISAM,MEMORY, andMERGE).HIGH_PRIORITY不能用于SELECT语句,这些语句是UNION的一部分。HIGH_PRIORITYcannot be used withSELECTstatements that are part of aUNION.STRAIGHT_JOIN强制优化器按照FROM子句中列出的顺序连接表。你可以使用它来加速查询,如果优化器以非最佳顺序连接表。STRAIGHT_JOIN也可以用于table_references列表中。见第 15.2.13.2 节,“JOIN 子句”.STRAIGHT_JOINforces the optimizer to join the tables in the order in which they are listed in theFROMclause. You can use this to speed up a query if the optimizer joins the tables in nonoptimal order.STRAIGHT_JOINalso can be used in thetable_referenceslist. See Section 15.2.13.2, “JOIN Clause”.STRAIGHT_JOINdoes not apply to any table that the optimizer treats as aconst或者systemtable. Such a table produces a single row, is read during the optimization phase of query execution, and references to its columns are replaced with the appropriate column values before query execution proceeds. These tables appear first in the query plan displayed byEXPLAIN。参见Section 10.8.1, “Optimizing Queries with EXPLAIN”. This exception may not apply toconst或者systemtables that are used on theNULL-complemented side of an outer join (that is, the right-side table of aLEFT JOINor the left-side table of aRIGHT JOIN.STRAIGHT_JOINdoes not apply to any table that the optimizer treats as aconstorsystemtable. Such a table produces a single row, is read during the optimization phase of query execution, and references to its columns are replaced with the appropriate column values before query execution proceeds. These tables appear first in the query plan displayed byEXPLAIN. See Section 10.8.1, “Optimizing Queries with EXPLAIN”. This exception may not apply toconstorsystemtables that are used on theNULL-complemented side of an outer join (that is, the right-side table of aLEFT JOINor the left-side table of aRIGHT JOIN.SQL_BIG_RESULT或SQL_SMALL_RESULT可以与GROUP BY或DISTINCT一起使用,分别告诉优化器该结果集有多行或较小。对于SQL_BIG_RESULT直接使用基于磁盘的临时表(如果创建的话),并且更倾向于排序,而不是使用带有键的临时表,GROUP BY元素。对于SQL_SMALL_RESULT使用内存中的临时表来存储结果表,而不是使用排序。这通常不需要。SQL_BIG_RESULTorSQL_SMALL_RESULTcan be used withGROUP BYorDISTINCTto tell the optimizer that the result set has many rows or is small, respectively. ForSQL_BIG_RESULT, MySQL directly uses disk-based temporary tables if they are created, and prefers sorting to using a temporary table with a key on theGROUP BYelements. ForSQL_SMALL_RESULT, MySQL uses in-memory temporary tables to store the resulting table instead of using sorting. This should not normally be needed.SQL_BUFFER_RESULT强制将结果放入临时表中。这有助于 MySQL 提前释放表锁,并在发送结果集到客户端需要较长时间的情况中有所帮助。该修饰符只能用于顶层SELECT语句,不能用于子查询或后续UNIONSQL_BUFFER_RESULTforces 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. This modifier can be used only for top-levelSELECTstatements, not for subqueries or followingUNION.SQL_CALC_FOUND_ROWS告诉 MySQL 计算结果集中将有多少行,忽略任何LIMIT子句。行数随后可以通过SELECT FOUND_ROWS()。参见 第 14.15 节,“信息函数”。SQL_CALC_FOUND_ROWStells MySQL to calculate how many rows there would be in the result set, disregarding anyLIMITclause. The number of rows can then be retrieved withSELECT FOUND_ROWS(). See Section 14.15, “Information Functions”.NoteSQL_CALC_FOUND_ROWS查询修饰符及其配套的FOUND_ROWS()函数已被弃用;预计它们将在未来版本的 MySQL 中被移除。有关另一种策略的信息,请参见FOUND_ROWS()TheSQL_CALC_FOUND_ROWSquery modifier and accompanyingFOUND_ROWS()function are deprecated; expect them to be removed in a future version of MySQL. See the description ofFOUND_ROWS()for information about an alternative strategy.描述。
SQL_CACHE和SQL_NO_CACHE修饰符曾用于 MySQL 8.4 之前的查询缓存。查询缓存在 MySQL 8.4 中被移除。SQL_CACHE修饰符也被移除。SQL_NO_CACHE已被弃用,且无影响;预计未来 MySQL 版本会移除。TheSQL_CACHEandSQL_NO_CACHEmodifiers were used with the query cache prior to MySQL 8.4. The query cache was removed in MySQL 8.4. TheSQL_CACHEmodifier was removed as well.SQL_NO_CACHEis deprecated, and has no effect; expect it to be removed in a future MySQL release.