假如我又一串数字在G这一列,数字大多为60015这样的五位数,而我想将其中尾数为4,5,9的这些数字提取出来,请问怎么用EXCEL函数提取?
可选中1个或多个下面的关键词,搜索相关资料。也可直接点“搜索资料”搜索整个问题。
可选中1个或多个下面的关键词,搜索相关资料。也可直接点“搜索资料”搜索整个问题。
获得全国计算机应用技术证书
比如要提取A1单元格中第5个字符起的6个字符,则这个公式可以写成
返回文本字符串中从指定位置开始的特定数目的字符,该数目由用户指定。
Text 是包含要提取字符的文本字符串。
Start_num 是文本中要提取的第一个字符的位置。文本中第一个字符的 start_num 为 1,以此类推。
Num_chars 指定希望 MID 从文本中返回字符的个数。
本回答由电脑网络分类达人 董辉推荐
比如要在H列判断结果,在H1输入公式:
将H1的公式向下复制就行了。
一个字符串是一个字符序列,由单引号(“'”)或双引号(“"”)字符(后者只有你不在ANSI模式运行)包围。例如:
在字符串内,某个顺序有特殊的意义。这些顺序的每一个以一条反斜线(“\”)开始,称为转义字符。MySQL识别下列转义字符:
注意,如果你在某些正文环境中使用“\%”或“\%_”,这些将返回字符串“\%”和“\_”而不是“%”和“_”。
有几种方法在一个字符串内包括引号:
下面显示的SELECT
演示引号和转义如何工作:
如果你想要把二进制数据插入到一个BLOB
列,下列字符必须由转义序列表示:
Perl中,你可以使用DBI
包中的quote
方法变换特殊的字符到正确的转义序列。见。
你应该在任何可能包含上述任何特殊字符的字符串上使用转义函数!
整数表示为一个数字顺序。浮点数使用“.”作为一个十进制分隔符。这两种类型的数字可以前置“-”表明一个负值。
该函数对多字节是可靠的。
str
。
该函数对多字节可靠的。
str
,在位置pos
起始的子串且len
个字符长得子串由字符串newstr
代替。
该函数对多字节是可靠的。
2
,返回str2
,等等。如果N
小于1
或大于参数个数,返回NULL
。ELT()
是FIELD()
反运算。
str
在由N
子串组成的表strlist
之中,返回一个1
到N
的值。一个字符串表是被“,”分隔的子串组成的一个字符串。如果第一个参数是一个常数字符串并且第二个参数是一种类型为SET
的列,FIND_IN_SET()
函数被优化而使用位运算!如果str
不是在strlist
里面或如果strlist
是空字符串,返回0
。如果任何一个参数是NULL
,返回NULL
。如果第一个参数包含一个“,”,该函数将工作不正常。
bits
集合中的的字符串组成。str1
对应于位0,str2
对应位1,等等。在str1
, str2
,
...
中的NULL
串不添加到结果中。
str
,根据当前字符集映射(缺省是ISO-8859-1 Latin1)把所有的字符改变成小写。该函数对多字节是可靠的。
str
,根据当前字符集映射(缺省是ISO-8859-1 Latin1)把所有的字符改变成大写。该函数对多字节是可靠的。
该函数对多字节是可靠的。
max_allowed_packet
。如果文件不存在或由于上面原因之一不能被读出,函数返回NULL
。
MySQL必要时自动变换数字为字符串,并且反过来也如此:
如果你想要明确地变换一个数字到一个字符串,把它作为参数传递到CONCAT()
。
如果字符串函数提供一个二进制字符串作为参数,结果字符串也是一个二进制字符串。被变换到一个字符串的数字被当作是一个二进制字符串。这仅影响比较。
对于每个类型拥有的值范围以及并且指定日期何时间值的有效格式的描述见。
这里是一个使用日期函数的例子。下面的查询选择了所有记录,其date_col
的值是在最后30天以内:
date
的星期索引(1
=星期天,2
=星期一, ……7
=星期六)。这些索引值对应于ODBC标准。
date
的星期索引(0
=星期一,1
=星期二, ……6
= 星期天)。
date
的月份中日期,在1
到31
范围内。
date
在一年中的日数, 在1
到366
范围内。
date
的月份,范围1
到12
。
date
的星期名字。
date
的月份名字。
date
一年中的季度,范围1
到4
。
date
的周数,范围在0
到52
。2个参数形式WEEK()
允许你指定星期是否开始于星期天或星期一。如果第二个参数是0
,星期从星期天开始,如果第二个参数是1
,从星期一开始。
time
的小时,范围是0
到23
。
time
的分钟,范围是0
到59
。
time
的秒数,范围是0
到59
。
N
个月到阶段P
(以格式YYMM
或YYYYMM
)。以格式YYYYMM
返回值。注意阶段参数P
不是日期值。
P1
和P2
之间月数,P1
和P2
应该以格式YYMM
或YYYYMM
。注意,时期参数P1
和P2
不是日期值。
+
和-
而不是DATE_ADD()
和DATE_SUB()
。(见例子)date
是一个指定开始日期的DATETIME
或DATE
值,expr
是指定加到开始日期或从开始日期减去的间隔值一个表达式,expr
是一个字符串;它可以以一个“-”开始表示负间隔。type
是一个关键词,指明表达式应该如何被解释。EXTRACT(type
FROM date)
函数从日期中返回“type”间隔。下表显示了type
和expr
参数怎样被关联:
MySQL在expr
格式中允许任何标点分隔符。表示显示的是建议的分隔符。如果date
参数是一个DATE
值并且你的计算仅仅包含YEAR
、MONTH
和DAY
部分(即,没有时间部分),结果是一个DATE
值。否则结果是一个DATETIME
值。
如果你指定太短的间隔值(不包括type
关键词期望的间隔部分),MySQL假设你省掉了间隔值的最左面部分。例如,如果你指定一个type
是DAY_SECOND
,值expr
被希望有天、小时、分钟和秒部分。如果你象"1:10"
这样指定值,MySQL假设日子和小时部分是丢失的并且值代表分钟和秒。换句话说,"1:10"
MINUTE_SECOND
的方式解释,这对那MySQL解释TIME
值表示经过的时间而非作为一天的时间的方式有二义性。如果你使用确实不正确的日期,结果是NULL
。如果你增加MONTH
、YEAR_MONTH
或YEAR
并且结果日期大于新月份的最大值天数,日子在新月用最大的天调整。
注意,从前面的例子中词INTERVAL
和type
关键词不是区分大小写的。
date
,返回一个天数(从0年的天数)。
TO_DAYS()
不打算用于使用格列高里历(1582)出现前的值。
N
,返回一个DATE
值。
TO_DAYS()
不打算用于使用格列高里历(1582)出现前的值。
format
字符串格式化date
值。下列修饰符可以被用在format
字符串中:
缩写的星期名字(Sun ……Sat )
|
月份中的天数, 数字(00 ……31 )
|
月份中的天数, 数字(0 ……31 )
|
缩写的月份名字(Jan ……Dec )
|
星期(0 ……52 ), 这里星期天是星期的第一天
|
星期(0 ……52 ), 这里星期一是星期的第一天
|
所有的其他字符不做解释被复制到结果中。
MySQL3.23中,在格式修饰符字符前需要%
。在MySQL更早的版本中,%
是可选的。
DATE_FORMAT()
函数一样使用,但是format
字符串只能包含处理小时、分钟和秒的那些格式修饰符。其他修饰符产生一个NULL
值或0
。
'YYYY-MM-DD'
或YYYYMMDD
格式返回今天日期值,取决于函数是在一个字符串还是数字上下文被使用。
'HH:MM:SS'
或HHMMSS
格式返回当前时间值,取决于函数是在一个字符串还是在数字的上下文被使用。
'YYYY-MM-DD HH:MM:SS'
或YYYYMMDDHHMMSS
格式返回当前的日期和时间,取决于函数是在一个字符串还是在数字的上下文被使用。
format
字符串格式化。format
可以包含与DATE_FORMAT()
函数列出的条目同样的修饰符。
seconds
参数,变换成小时、分钟和秒,值以'HH:MM:SS'
或HHMMSS
格式化,取决于函数是在一个字符串还是在数字上下文中被使用。
time
参数,转换成秒。
如果没有当前的数据库,DATABASE()
返回空字符串。
在MySQL 3.22.11或以后版本中,这包括用户名和客户主机名。你可以象这样只提取用户名部分(值是否包括主机名部分均可工作):
str
计算一个口令字符串。该函数被用于为了在user
授权表的Password
列中存储口令而加密MySQL口令。
PASSWORD()
加密是非可逆的。PASSWORD()
不以与Unix口令加密的相同的方法执行口令加密。你不应该假定如果你的Unix
口令和你的MySQL口令是一样的,PASSWORD()
将导致与在Unix口令文件存储的相同的加密值。见ENCRYPT()
。
如果crypt()
在你的系统上不可用,ENCRYPT()
总是返回NULL
。ENCRYPT()
只保留str
起始8个字符而忽略所有其他,至少在某些系统上是这样。这将由底层的crypt()
系统调用的行为决定。
pass_str
作为口令加密str
。为了解密结果,使用DECODE()
。结果是一个二进制字符串,如果你想要在列中保存它,使用一个BLOB
列类型。
这是一个“RSA数据安全公司的MD5消息摘要算法”。
AUTO_INCREMENT
列的最后一个自动产生的值。见。
产生的最后ID以每个连接为基础在服务器被维护,它不会被其他客户改变。如果你更新另外一个有非魔术值(即,不是NULL
和不是0
的一个值)的AUTO_INCREMENT
列,它甚至不会被改变。如果expr
作为一个参数在一个UPDATE
子句的LAST_INSERT_ID()
里面给出,那么参数值作为一个LAST_INSERT_ID()
值被返回。这可以用来模仿顺序:首先创建表:
然后表能被用来产生顺序号,象这样:
你可以不调用LAST_INSERT_ID()
而产生顺序,但是这样使用函数的实用程序在服务器上自动维护ID值作为最后自动产生的值。你可以检索新的ID值,就像你能读入正常MySQL中的任何正常的AUTO_INCREMENT
值一样。例如,LAST_INSERT_ID()
(没有一个参数
X
为类似于格式'#,###,###.##'
,四舍五入到D
为小数。如果D
为0
,结果将没有小数点和小数部分。
str
给定的一个名字的锁定,第二个timeout
为超时。如果锁定成功获得,返回1
,如果尝试超时了,返回0
,或如果发生一个错误,返回NULL
(例如从存储器溢出或线程用mysqladmin
kill
被杀死)。当你执行RELEASE_LOCK()
时、执行一个新的GET_LOCK()
或线程终止时,一个锁定被释放。该函数可以用来实现应用锁或模拟记录锁,它阻止其他客户用同样名字的锁定请求;赞成一个给定的锁定字符串名字的客户可以使用字符串执行子协作建议的锁定。
str
命名的通过GET_LOCK()
获得的锁。如果锁被释放,返回1
,如果锁没被这个线程锁定(在此情况下锁没被释放)返回0
,并且如果命名的锁不存在,返回NULL
。如果锁从来没有通过调用GET_LOCK()
获得或如果它已经被释放了,锁将不存在。
BENCHMARK()
函数重复count
Times次执行表达式expr
,它可以用于计时MySQL处理表达式有多快。结果值总是0
。意欲用于mysql
客户,它报告查询的执行时间。
报告的时间是客户端的经过时间,不是在服务器端的CPU时间。执行BENCHMARK()
若干次可能是明智的,并且注意服务器机器的负载有多重来解释结果。
如果你在不包含GROUP BY
子句的一个语句中使用聚合函数,它等价于聚合所有行。
SELECT
语句检索出来的行的非NULL
值的数目。
COUNT(*)
在它返回的检索出来的行数目上有些不同,不管他们是否包含NULL
值。如果SELECT
从一个表检索,或没有检索出其他列并且没有WHERE
子句,COUNT(*)
被优化以便快速地返回。例如:
在MySQL中,你可以通过给出一个表达式列表以得到不同的表达式组合的数目。在 ANSI SQL中,你可能必须在CODE(DISTINCT ..)
内进行所有表达式的连接。
expr
的平均值。
expr
的最小或最大值。MIN()
和MAX()
可以有一个字符串参数;在这种的情况下,他们返回最小或最大的字符串值。
expr
的和。注意,如果返回的集合没有行,它返回NULL!
expr
里所有位的位或。计算用 64 位(BIGINT
)精度进行。
expr
里所有位的位与。计算用 64 位(BIGINT
)精度进行。
BY部分的SELECT
表达式中使用列或计算,这表示这个组的任何可能值。你可以使用它是性能更好,避免在不必要的项目上排序和分组。例如,你在下列查询中不需要在customer.name
上聚合:
如果你从GROUP BY
部分省略的列在组中不是唯一的,不要使用这个功能。
在某些情况下,你可以使用MIN()
和MAX()
获得一个特定的列值,即使它不是唯一的。下例给出从包含sort
列中最小值的行的column
值:
BY子句中使用表达式。你可以通过使用表达式的一个别名解决此限制:
在MySQL
3.23中,你可以这样做:
CREATE DATABASE
用给定的名字创建一个数据库。允许的数据库名字规则在中给出。如果数据库已经存在,发生一个错误。
在MySQL中的数据库实现成包含对应数据库中表的文件的目录。因为数据库在初始创建时没有任何表,CREATE DATABASE
语句只是在MySQL数据目录下面创建一个目录。
你也可以用mysqladmin
创建数据库。见。
DROP DATABASE
删除数据库中的所有表和数据库。要小心地使用这个命令!
DROP DATABASE
返回从数据库目录被删除的文件的数目。通常,这3倍于表的数量,因为每张表对应于一个“.MYD”文件、一个“.MYI”文件和一个“.frm”文件。
在MySQL 3.22或以后版本中,你可以使用关键词IF EXISTS
阻止一个错误的发生,如果数据库不存在。
你也可以用mysqladmin
丢弃数据库。见。
CREATE TABLE
在当前数据库中用给出的名字创建一个数据库表。允许的表名的规则在中给出。如果当前数据库不存在或如果表已经存在,出现一个错误。
在MySQL3.22或以后版本中,表名可以被指定为db_name.tbl_name
,不管有没有当前的数据库都可以。
在MySQL3.23中,当你创建一张表时,你可以使用TEMPORARY
关键词。如果一个连接死掉,临时表将自动被删除,并且其名字是按连接命名。这意味着,2个不同的连接能使用相同的暂时表的名字而不会彼此冲突或与相同名字的现有数据库表冲突。(现有的表被隐蔽直到临时表被删除)。
在MySQL3.23或以后版本中,你可以使用关键词IF NOT EXISTS
以便如果表已经存在不发生一个错误。注意,无法证实表结构是相同的。
每张表tbl_name
由在数据库目录的一些文件表示。在MyISAM类型的表的情况下,你将得到:
对于各种列类型的性质的更多信息,见。
NULL
也不指定NOT NULL
,列被视为指定了NULL
。
AUTO_INCREMENT
。当你插入NULL
值(推荐)或0
到一个AUTO_INCREMENT
列中时,列被设置为value+1
,在此value
是当前表中的列的最大值。AUTO_INCREMENT
顺序从1
开始。见。如果你删除了包含一个AUTO_INCREMENT
列的最大值的行,值将被重新使用。如果你删除表中所有的行,顺序重新开始。注意:每个表只能有一个AUTO_INCREMENT
列,并且它必须被索引。为了使做MySQL兼容一些
ODBC 应用程序,用下列查询你可以找出最后插入的行:
NULL
值对于TIMESTAMP
列的处理不同于其他列类型。你不能在一个TIMESTAMP
列中存储一个文字NULL
;设置列为NULL
将把它设成当前的日期和时间。因为TIMESTAMP
列表现就这样,NULL
和NOT
NULL
属性不以一般方式运用并且如果你指定它们,将被忽略。在另一方面,为了使它MySQL客户更容易地使用TIMESTAMP
列,服务器报告这样的列可以被赋值NULL
(
tbl_name得到有关你的表的描述时,你就会明白。注意,设置一个TIMESTAMP
列为0
不同于将它设置为NULL
,因为0
是一个有效的TIMESTAMP
值。
DEFAULT
值,MySQL自动地分配一个。如果列可以取NULL
作为值,缺省值是NULL
。如果列被声明为NOT NULL
,缺省值取决于列类型:
AUTO_INCREMENT
属性的数字类型,缺省值是0
。对于一个AUTO_INCREMENT
列,缺省值是在顺序中的下一个值。
TIMESTAMP
的日期和时间类型,缺省值是该类型适当的“零”值。对于表中第一个TIMESTAMP
列,缺省值是当前的日期和时间。见。
ENUM
的字符串类型,缺省是空字符串。对于ENUM
,缺省值是第一个枚举值。
UNIQUE
键只能有不同的值。如果你试图用匹配现有行的键来增加新行,发生一个错误。
PRIMARY KEY
是一个唯一KEY
,它有额外的限制,即所有的关键列必须被定义为NOT NULL
。在MySQL中,键被命名为PRIMARY
。一张表只能有一个PRIMARY
一个
PRIMARY KEY可以是一个多列索引。然而,你不能在一个列说明中使用PRIMARY KEY
的关键字属性创建一个多列索引。这样做将仅仅标记单个列作为主键。你必须使用PRIMARY KEY(index_col_name, ...)
语法。
index_col_name
相同的名字,用一个可选的suffix(_2
, _3
, ...
)使它唯一。你能使用SHOW INDEX FROM tbl_name
看到一张表的索引名字。见。
MyISAM
表类型支持可以有NULL
值的列上的索引。在其他情况下,你必须声明这样的列为NOT NULL
,否则导致一个错。
col_name(length)
语法,你可以指定仅使用部分的CHAR
或VARCHAR
列的一个索引。这能使索引文件变得更小。见。
MyISAM
表类型支持BLOB
和TEXT
列的索引。当在一个BLOB
或TEXT
列上放置索引时,你必须总是指定索引的长度:
FOREIGN KEY
、CHECK
和REFERENCES
子句实际上不做任何事情,其语法仅仅提供兼容性,使得它更容易从其他的SQL服务器移植代码并运行借助引用创建表的应用。见。
NULL
列占据额外一位,取舍到最接近的字节。
全新二进制可移植的表处理器 |
用于该表的数据仅仅存储在内存中 |
见。其他表选项被用来优化表的行为。在大多数情况下,你不必指定他们任何一个。选项对所有表都适用,如果不是则说明。
你的表的平均行长度的近似值。你只需要为有变长记录的表设置它。 |
如果你想要MySQL对每行维持一个校验和(使表变得更慢以更新但是使它更容易找出损坏的表)设置它为1 ( MyISAM ) |
对于你的表的一篇60个字符的注释 |
你计划在表中存储的行的最大数目 |
你计划在表中存储的行的最小数目 |
如果你想要有更小的索引,将它设为1。这通常使的更新更慢并且读取更快(MyISAM,ISAM)。 |
用一个口令加密.frm 文件。该选项在标准MySQL版本中不做任何事情。
|
如果想要推迟关键表的更新直到表被关闭(MyISAM),将它设置为1。 |
定义行应该如何被存储(为了将来)。 |
当你使用一个MyISAM
表时,MySQL使用max_rows * avg_row_length
的乘积决定最终的表将有多大。如果你不指定上面的任何选项,对一个表的最大尺寸将是4G(或2G,如果你的操作系统仅支持2G的表)。
CREATE
语句后指定一个SELECT
,MySQL将为在SELECT
中所有的单元创键新字段。例如:
这将创建一个有3个列的HEAP
表。注意如果在拷贝数据进表时发生任何错误,表将自动被删除。
在某些情况下,MySQL隐含地改变在一个CREATE TABLE
语句给出的一个列说明。(这也可能在ALTER TABLE
。)
VARCHAR
、TEXT
或BLOB
),所有大于3个字符的CHAR
列被改变为VARCHAR
列。这在任何方面都不影响你如何使用列;在MySQL中,VARCHAR
只是存储字符的一个不同方法。MySQL实施这种改变,是因为它节省空间并且使表操作更快捷。见。
TIMESTAMP
的显示尺寸必须是偶数且在2 ~ 14的范围内。如果你指定0显示尺寸或比14大,尺寸被强制为14。从1~13范围内的奇数值尺寸被强制为下一个更大的偶数。
TIMESTAMP
列里面存储一个文字NULL
;将它设为NULL
将设置为当前的日期和时间。因为TIMESTAMP
列表现就是这样,NULL
和NOT
NULL
属性不以一般的方式运用并且如果你指定他们,将被忽略。DESCRIBE tbl_name
总是报告该TIMESTAMP
列可能赋予了NULL
值。
如果你想要知道MySQL是否使用了除你指定的以外的一种列类型,在创建或改变你的表之后,发出一个DESCRIBE tbl_name
语句即可。
如果你使用myisampack
压缩一个表,可能会发生改变某些其他的列类型。见。
ALTER TABLE
允许你修改一个现有表的结构。例如,你可以增加或删除列、创造或消去索引、改变现有列的类型、或重新命名列或表本身。你也能改变表的注释和表的类型。见。
tbl_name显示你的列并没有被修改,这可能是MySQL因为在中描述的原因之一而忽略了你的修改。例如,如果你试图将一个VARCHAR
改为CHAR
,MySQL将仍然使用VARCHAR
,如果表包含其他变长的列。
ALTER TABLE
通过制作原来表的一个临时副本来工作。修改在副本上施行,然后原来的表被删除并且重新命名一个新的。这样做使得所有的修改自动地转向到新表,没有任何失败的修改。当ALTER TABLE
正在执行时,原来的桌可被其他客户读取。更新和写入表被延迟到新表准备好了为止。
IGNORE
没被指定,副本被放弃并且恢复原状。如果IGNORE
被指定,那么对唯一键有重复的行,只有使用第一行;其余被删除。
COLUMN
是一个纯粹的噪音且可以省略。
CHANGE old_col_name create_definition
子句重命名一个列。为了这样做,指定旧的和新的列名字和列当前有的类型。例如,重命名一个INTEGER
列,从a
到b
,你可以这样做:
如果你想要改变列的类型而非名字,就算他们是一样的,CHANGE
语法仍然需要2个列名。例如:
然而,在MySQL3.22.16a,你也可以使用MODIFY
来改变列的类型而不是重命名它:
CHANGE
或MODIFY
缩短一个列,一个索引存在于该列的部分(例如,如果你有一个VARCHAR
列的头10个字符的索引),你不能使列短于被索引的字符数目。
CHANGE
或MODIFY
改变一个列类型时,MySQL尽可能试图很好地变换数据到新类型。
FIRST
或ADD ... AFTER col_name
在一个表的行内在一个特定的位置增加列。缺省是增加到最后一列。
ALTER COLUMN
为列指定新的缺省值或删除老的缺省值。如果老的缺省值被删除且列可以是NULL
,新缺省值是NULL
。如果列不能是NULL
,MySQL赋予一个缺省值。缺省值赋值在中描述。
mysql_info()
,你能找出多少记录被拷贝, 和(当使用IGNORE
时)由于唯一键值的重复多少记录被删除。
FOREIGN KEY
、CHECK
和REFERENCES
子句实际上不做任何事情,他们的句法仅仅提供兼容性,使得更容易地从其他SQL服务器移植代码并且运行借助引用来创建表的应用程序。见。
这里是一个例子,显示了一些ALTER TABLE
用法。我们以一个如下创建的表t1
开始:
重命名表,从t1
到t2
:
在列d
上增加一个索引,并且使列a
为主键:
注意,我们索引了c
,因为AUTO_INCREMENT
柱必须被索引,并且另外我们声明c
为NOT NULL
,因为索引了的列不能是NULL
。
当你增加一个AUTO_INCREMENT
列时,自动地用顺序数字填入列值。
如果你删除了一个表的大部分或如果你用变长的行对一个表(有VARCHAR
、BLOB
或TEXT
列的表)做了改变,应该使用OPTIMZE TABLE
。删除的记录以一个链接表维持并且随后的INSERT
操作再次使用老记录的位置。你可以使用OPTIMIZE
TABLE
回收闲置的空间。
OPTIMIZE TABLE
通过制作原来的表的一个临时副本来工作。老的表子被拷贝到新表中(没有闲置的行),然后原来的表被删除并且重命名一个新的。这样做使得所有更新自动转向新的表,没有任何失败的更新。当时OPTIMIZE TABLE
正在执行时,原来的表可被另外的客户读取。对表的更新和写入延迟到新表是准备好为止。
DROP TABLE
删除一个或多个数据库表。所有表中的数据和表定义均被删除,故小心使用这个命令!
在MySQL 3.22或以后版本,你可以使用关键词IF EXISTS
类避免不存在表的一个错误发生。
如果你发出一个没有WHERE
子句的DELETE
,所有行都被删除。MySQL通过创建一个空表来完成,它比删除每行要快。在这种情况下,DELETE
返回零作为受影响记录的数目。(MySQL不能返回实际上被删除的行数,因为进行再创建而不是打开数据文件。只要表定义文件“tbl_name.frm”是有效的,表才能这样被再创建,即使数据或索引文件破坏了)。
如果你确实想要知道在你正在删除所有行时究竟有对少记录被删除,并且愿意承受速度上的惩罚,你可以这种形式的一个ELETE
语句:
如果你指定关键词LOW_PRIORITY
,DELETE
的执行被推迟到没有其他客户读取表后。
删除的记录以一个链接表维持并且随后的INSERT
操作再次使用老的记录位置。为了回收闲置的空间并减小文件大小,使用OPTIMIZE TABLE
语句或myisamchk
实用程序重新组织表。OPTIMIZE
rows
选项告诉服务器在控制被返回到客户之前,将要删除的最大行数,这可以用来保证一个特定DELETE
命令不会花太多的时间。你可以简单地重复DELETE
命令直到受影响的行数小于LIMIT
值。
SELECT
被用来检索从一个或多个表中精选的行。select_expression
指出你想要检索的列。SELECT
也可以用来检索不引用任何表的计算行。例如:
所有使用的关键词必须精确地以上面的顺序给出。例如,一个HAVING
子句必须跟在GROUP BY
子句之后和ORDER BY
子句之前。
SELECT
表达式可以用一个AS
给定一个别名,别名被用作表达式的列名并且能使用在ORDER BY
或HAVING
子句中。例如:
FROM table_references
子句指出从哪个表中检索行。如果你命名多个表,你正在执行一个联结(join)。对于联结的句法信息,见。
ORDER BY
和GROUP BY
子句引用,列位置从1开始。
为了以降序排列,把DESC
(下降 )关键词加到ORDER BY
子句中你要排序的列名前。缺省是升序;这也可以用ASC
关键词明确指定。
HAVING
子句能引用任何列或在select_expression
中命名的别名,它最后运用,就在项目被送到客户之前,没有优化。不要对因该在WHERE
子句中的项目使用HAVING
。例如,不能写成这样:
在MySQL 3.22.5或以后,你也能这样写查询:
在里面更老的MySQL版本中,你能这样写:
STRAIGHT_JOIN
强制优化器以其列在FROM
子句的次序联结(join)桌子。如果优化器以非最佳次序联结表,你能使用它加速查询。见。
SQL_SMALL_RESULT
能与GROUP BY
或DISTINCT
一起使用告诉优化器结果集将很小。在这种情况下,MySQL将使用快速临时表存储最终的表而不是使用排序。
SQL_BIG_RESULT
能与GROUP BY
或DISTINCT
一起使用以告诉优化器结果集合将有很多行。在这种情况下,如果需要,MySQL将直接使用基于磁盘的临时表。 MySQL
在这种情况下将选择用GROUP
BY
单元上的键值进行排序而不是做一个临时表。
HIGH_PRIORITY
将赋予SELECT
比一个更新表的语句更高的优先级,你应该仅对非常快的并且必须一次完成的查询使用它。 如果表为读而锁定或甚至有一个等待表释放的更新语句,一个SELECT HIGH_PRIORITY
将运行。
LIMIT
子句可以被用来限制SELECT
语句返回的行数。LIMIT
取1个或2个数字参数,如果给定2个参数,第一个指定要返回的第一行的偏移量,第二个指定返回行的最大数目。初始行的偏移量是0(不是1)。
如果给定一个参数,它指出返回行的最大数目。
BY字符以便能可靠地能读回文件。ASCII 0
被转义使它更容易用分页器观看。因为最终的文件不必须遵循SQL句法,没有别的东西需要转义。
如果你使用INTO DUMPFILE
而不是INTO OUTFILE
,MySQL将只写一行到文件中,没有任何列或行结束并且没有任何转义。如果你想要在一个文件存储一个blob,这是很有用的。
上述最后的LEFT OUTER JOIN
的句法只是为了与ODBC兼容而存在的。
INNER JOIN
和,
(逗号)在语义上是等价的,都是进行一个在使用的表之间的全联结。通常,你指定表应该如何用WHERE
条件联结起来。
ON
条件是可以用在一个WHERE
子句形式的任何条件。
LEFT JOIN
中没有右表的匹配记录,一个所有列设置为NULL
的行被用于右表。你可以使用这个事实指出表中在另一个表中没有对应记录的记录:
这个例子找出在table1
中所有的行,其id
值在table2
中不存在(即,所有table1
中的在table2
中没有对应行的行)。当然这假定table2.id
被声明为NOT NULL
。
USING
(column_list)
子句命名一系列必须存在于两个表中的列。 例如一个USING
子句:
被定义成在语义上等同一个这样的ON
表达式:
NATURAL LEFT JOIN
被定义为在语义上等同于一个有USING
子句命名在两表中存在的所有列的一个LEFT JOIN
。
STRAIGHT_JOIN
等同于JOIN
,除了左表在右表之前被读入,这能用于这些情况,联结优化器将表的顺序放错了。
tbl_name
是行应该被插入其中的表。列名表或SET
子句指出语句为那一列指定值。
expression
可以引用在一个值表先前设置的任何列。例如,你能这样:
LOW_PRIORITY
,INSERT
的执行被推迟到没有其他客户正在读取表。在这种情况下,客户必须等到插入语句完成后,如果表频繁使用,它可能花很长时间。这与INSERT DELAYED
让客马上继续正好相反。
INSERT
中指定关键词IGNORE
,表中任何复制一个现有PRIMARY
或UNIQUE
键的行被忽略并且不被插入。如果你不指定IGNORE
,插入如果有任何复制现有关键值的行被放弃。你可用C
DONT_USE_DEFAULT_FIELDS
选项配置,INSERT
语句产生一个错误,除非你明确对需要一个非NULL
值的所有列指定值。见。
ORDER BY
子句。
INSERT
语句的目的表不能出现在SELECT
查询部分的FROM
子句,因为这在ANSI SQL中被禁止让从你正在插入的表中SELECT
。(问题是SELECT
将可能发现在同一个运行期间内先前被插入的记录。当使用子选择子句时,情况能很容易混淆)
Duplicates
指出不能被插入的行的数量,因为他们与现有的唯一的索引值重复。Warnings
指出在出现某些问题时尝试插入列值的次数。在下列任何条件下都可能发生错误:
NULL
到被声明了NOT NULL
的列,列被设置为它的缺省值。
'10.34 a'
的值,拖尾的垃圾被剥去并仍然是数字部分被插入。如果值根本不是一个数字,列被设置到0
。
CHAR
、VARCHAR
、TEXT
或BLOB
列中。值被截断为列的最大长度。
对于INSERT
语句的DELAYED
选项是MySQL专属的选项-如果你客户有不能等到INSERT
完成,它是很有用的。当你为日记登录使用MySQL时,而且你也周期性地运行花很长时间完成的SELECT
语句,这是一个常见的问题。DELAYED
在面MySQL
当你使用INSERT DELAYED
时,客户将马上准备好,并且当表不被任何其他的线程使用时,行将被插入。
另一个使用INSERT DELAYED
的主要好处是从很多客户插入被捆绑在一起并且写进一个块。这比做很多单独的插入要来的快。
注意,当前排队的行只是存储在内存中,直到他们被插入到表中。这意味着,如果你硬要杀死mysqld
(kill -9
)或如果mysqld
出人意料地死掉,没被写进磁盘的任何排队的行被丢失!
下列详细描述当你为INSERT
或REPLACE
使用DELAYED
选项时,发生什么。在这个描述中,“线程”是收到一个INSERT DELAYED
命令的线程并且“处理器”是处理所有对于一个特定表的INSERT DELAYED
语句。
DELAYED
语句时,如果不存在这样的处理程序,一个处理器线程被创建以处理对于该表的所有DELAYED
语句。
DELAYED
锁;如果没有,它告诉处理程序去获得。即使其他的线程有在表上的一个READ
或WRITE
锁,也能获得DELAYED
锁。然而,处理程序将等待所有ALTER TABLE
锁或FLUSH
TABLES
以保证表结构是最新的。
INSERT
语句,但不是将行写入表,它把最后一行的副本放进被处理器线程管理的一个队列。任何语法错误都能被线程发觉并报告给客户程序。
AUTO_INCREMENT
值;它不能从服务器获得它们,因为INSERT
在插入操作完成前返回。如果你使用C API,同样原因,mysql_info()
函数不返回任何有意义的东西。
delayed_insert_limit
行后,处理器检查是否任何SELECT
语句仍然是未完成,如果这样,在继续之前允许执行这些语句。
delayed_insert_timeout
秒内没有收到新的INSERT DELAYED
命令,处理器终止。
delayed_queue_size
行在一个特定的处理器队列中未解决,线程等待直到队列有空间。这有助于保证mysqld
服务器对延迟的内存队列不使用所有内存。
INSERT
命令。如果你在它之后执行一个INSERT DELAYED
,将创建一个新的处理器线程。
INSERT DELAYED
处理器已经运行,INSERT DELAYED
命令有比正常INSERT
更高的优先级!其他更新命令将必须等到INSERT DELAY
排队变空、杀死处理器线程(用KILL
下列状态变量提供了关于
INSERT DELAYED命令的信息:
注意如果桌子不在使用,INSERT DELAYED
比一个正常的INSERT
慢。对服务器也有额外开销来处理你对它使用INSERT DELAYED
的每个表的一个单独线程。这意味着,你应该只在你确实肯定需要它的时候才使用INSERT DELAYED
!
REPLACE
功能与INSERT
完全一样,除了如果在表中的一个老记录具有在一个唯一索引上的新记录有相同的值,在新记录被插入之前,老记录被删除。见。
LOAD DATA INFILE
语句从一个文本文件中以很高的速度读入一个表中。如果指定LOCAL
关键词,从客户主机读文件。如果LOCAL
没指定,文件必须位于服务器上。(LOCAL
在MySQL3.22.6或以后版本中可用。)
为了安全原因,当读取位于服务器上的文本文件时,文件必须处于数据库目录或可被所有人读取。另外,为了对服务器上文件使用LOAD DATA INFILE
,在服务器主机上你必须有file的权限。见。
如果你指定关键词LOW_PRIORITY
,LOAD DATA
语句的执行被推迟到没有其他客户读取表后。
使用LOCAL
将比让服务器直接存取文件慢些,因为文件的内容必须从客户主机传送到服务器主机。在另一方面,你不需要file权限装载本地文件。
你也可以使用mysqlimport
实用程序装载数据文件;它由发送一个LOAD DATA INFILE
命令到服务器来运作。
--local
选项使得mysqlimport
从客户主机上读取数据。如果客户和服务器支持压缩协议,你能指定--compress
在较慢的网络上获得更好的性能。
当在服务器主机上寻找文件时,服务器使用下列规则:
注意这些规则意味着一个像“./myfile.txt”给出的文件是从服务器的数据目录读取,而作为“myfile.txt”给出的一个文件是从当前数据库的数据库目录下读取。也要注意,对于下列哪些语句,对db1
文件从数据库目录读取,而不是db2
:
REPLACE
和IGNORE
关键词控制对现有的唯一键记录的重复的处理。如果你指定REPLACE
,新行将代替有相同的唯一键值的现有行。如果你指定IGNORE
,跳过有唯一键的现有行的重复行的输入。如果你不指定任何一个选项,当找到重复键键时,出现一个错误,并且文本文件的余下部分被忽略时。
如果你使用LOCAL
关键词从一个本地文件装载数据,服务器没有办法在操作的当中停止文件的传输,因此缺省的行为好像IGNORE
被指定一样。
OUTFILE,为了将文件读回数据库,使用LOAD DATA INFILE
。两个命令的FIELDS
和LINES
子句的语法是相同的。两个子句是可选的,但是如果指定两个,FIELDS
必须在LINES
之前。
如果你不指定一个FIELDS
子句,缺省值与如果你这样写的相同:
如果你不指定一个LINES
子句,缺省值与如果你这样写的相同:
换句话说,缺省值导致读取输入时,LOAD DATA INFILE
表现如下:
注意,为了写入FIELDS ESCAPED BY '\\'
,对作为一条单个的反斜线被读取的值,你必须指定2条反斜线值。
IGNORE number LINES
选项可被用来忽略在文件开始的一个列名字的头:
当你与LOAD DATA INFILE
一起使用SELECT ... INTO OUTFILE
将一个数据库的数据写进一个文件并且随后马上将文件读回数据库时,两个命令的字段和处理选项必须匹配,否则,LOAD DATA INFILE
将不能正确解释文件的内容。假定你使用SELECT ... INTO
OUTFILE
将由逗号分隔的字段写入一个文件:
为了将由逗号分隔的文件读回来,正确的语句将是:
相反,如果你试图用下面显示的语句读取文件,它不会工作,因为它命令LOAD DATA INFILE
在字段之间寻找定位符:
可能的结果是每个输入行将被解释为单个的字段。
LOAD DATA INFILE
能被用来读取从外部来源获得的文件。例如,以dBASE格式的文件将有由逗号分隔并用双引号包围的字段。如果文件中的行由换行符终止,下面显示的命令说明你将用来装载文件的字段和行处理选项:
BY值可以是超过一个字符。例如,写入由回车换行符对(CR+LF)终止的行,或读取包含这样行的一个文件,指定一个LINES TERMINATED BY '\r\n'
子句。
注意,一个字段值中的ENCLOSED BY
字符的出现通过用ESCAPED BY
字符作为其前缀来转义。也要注意,如果你指定一个空ESCAPED BY
值,可能产生不能被LOAD DATA
INFILE
正确读出的输出。例如,如果转义字符为空,上面显示的输出显示如下。注意到在第四行的第二个字段包含跟随引号的一个逗号,它(错误地)好象要终止字段:
对于输入,ENCLOSED BY
字符如果存在,它从字段值的尾部被剥去。(不管是否指定OPTIONALLY
都是这样;OPTIONALLY
对于输入解释不起作用)由ENCLOSED BY
字符领先的ESCAPED
BY
字符出现被解释为当前字段值的一部分。另外,出现在字段中重复的ENCLOSED BY
被解释为单个ENCLOSED BY
字符,如果字段本身以该字符开始。例如,如果ENCLOSED BY '"'
被指定,引号如下处理:
FIELDS ESCAPED BY
控制如何写入或读出特殊字符。如果FIELDS ESCAPED BY
字符不是空的,它被用于前缀在输出上的下列字符:
0
(实际上将后续转义字符写成 ASCII'0'
,而不是一个零值字节)
如果FIELDS ESCAPED BY
字符是空的,没有字符被转义。指定一个空转义字符可能不是一个好主意,特别是如果在你数据中的字段值包含刚才给出的表中的任何字符。
对于输入,如果FIELDS ESCAPED BY
字符不是空的,该字符的出现被剥去并且后续字符在字面上作为字段值的一个部分。例外是一个转义的“0”或“N”(即,\0
或\N
,如果转义字符是“\”)。这些序列被解释为ASCII
0
(一个零值字节)和NULL
。见下面关于NULL
处理的规则。
对于更多关于“\”- 转义句法的信息,见。
在某些情况下,字段和行处理选项相互作用:
''
),一个固定行(非限定的)格式被使用。用固定行格式,在字段之间不使用分隔符。相反,列值只用列的“显示”宽度被写入和读出。例如,如果列被声明为INT(7)
,列的值使用7个字符的字段被写入。对于输入,列值通过读取7个字符获得。固定行格式也影响NULL
值的处理;见下面。注意如果你正在使用一个多字节字符集,固定长度格式将不工作。
NULL
值的处理有多种,取决于你使用的FIELDS
和LINES
选项:
NULL
作为一个空字符串被写入。注意,在写入文件时,这导致NULL
和空字符串在表中不能区分,因为他们都作为空字符串被写入。如果在读回文件时需要能区分这两者,你应该不使用固定行格式。
LOAD DATA INFILE
不能正确地解释输入。例如,下列FIELDS
子句将导致问题:
LOAD DATA INFILE
不能正确地决定字段或行值在哪儿结束。
下列例子装载所有persondata
表的行:
没有指定字段表,所以LOAD DATA INFILE
期望输入行对每个表列包含一个字段。使用缺省FIELDS
和LINES
值。
如果你希望仅仅装载一张表的某些列,指定一个字段表:
如果在输入文件中的字段顺序不同于表中列的顺序,你也必须指定一个字段表。否则,MySQL不能知道如何匹配输入字段和表中的列。
如果一个行有很少的字段,对于不存在输入字段的列被设置为缺省值。缺省值赋值在中描述。
如果字段值缺省,空字段值有不同的解释:
0
。
如果列有一个NULL
,或(只对第一个TIMESTAMP
列)在指定一个字段表时,如果TIMESTAMP
列从字段表省掉,TIMESTAMP
列只被设置为当前的日期和时间。
如果输入行有太多的字段,多余的字段被忽略并且警告数字加1。
LOAD DATA INFILE
认为所有的输入是字符串,因此你不能像你能用INSERT
语句的ENUM
或SET
列的方式使用数字值。所有的ENUM
和SET
值必须作为字符串被指定!
如果你正在使用C API,当LOAD DATA INFILE
查询完成时,你可通过调用API函数mysql_info()
得到有关查询的信息。信息字符串的格式显示在下面:
当值通过INSERT
语句插入时,在某些情况下出现警告(见),除了在输入行中有太少或太多的字段时,LOAD DATA INFILE
也产生警告。警告没被存储在任何地方;警告数字仅能用于表明一切是否顺利。如果你得到警告并且想要确切知道你为什么得到他们,一个方法是使用SELECT ... INTO
OUTFILE
到另外一个文件并且把它与你的原版输入文件比较。
UPDATE
用新值更新现存表中行的列,SET
子句指出哪个列要修改和他们应该被给定的值,WHERE
子句,如果给出,指定哪个行应该被更新,否则所有行被更新。
如果你指定关键词LOW_PRIORITY
,执行UPDATE
被推迟到没有其他客户正在读取表时。
如果你从一个表达式的tbl_name
存取列,UPDATE
使用列的当前值。例如,下列语句设置age
为它的当前值加1:
UPDATE
赋值是从左到右计算。例如,下列语句两倍age
列,然后加1:
如果你设置列为其它当前有的值,MySQL注意到这点并且不更新它。
UPDATE
返回实际上被改变的行的数量。在MySQL 3.22或以后版本中,C API函数mysql_info()
返回被匹配并且更新的行数和在UPDATE
期间发生警告的数量。
在MySQL3.23中,你可使用LIMIT #
来保证只有一个给定数量的行被改变。
USE db_name
语句告诉MySQL使用db_name
数据库作为随后的查询的缺省数据库。数据库保持到会话结束,或发出另外一个USE
语句:
利用USE
语句使得一个特定的数据库称为当前数据库并不阻止你访问在另外的数据库中的表。下面的例子访问db1
数据库中的author
表和db2
数据库中的editor
表:
USE
语句提供了Sybase的兼容性。
如果你想要清除一些MySQL使用内部缓存,你应该使用FLUSH
命令。为了执行FLUSH
,你必须有reload权限。
清空主机缓存表。如果你的某些主机改变IP数字,或如果你得到错误消息Host ... is
blocked ,你应该清空主机表。当在连接MySQL服务器时,对一台给定的主机有多于max_connect_errors 个错误连续不断地发生,MySQL认定某些东西错了并且阻止主机进一步的连接请求。清空主机表允许主机再尝试连接。见)。你可用-O
|
关闭并且再打开标准和更新记录文件。如果你指定了一个没有扩展名的更新记录文件,新的更新记录文件的扩展数字将相对先前的文件加1。 |
从mysql 数据库授权表中重新装载权限。
|
重置大多数状态变量到0。 |
每个对mysqld
的连接以一个单独的线程运行。你可以用看SHOW PROCESSLIST
命令察看哪个线程正在运行,并且用KILL thread_id
命令杀死一个线程。
如果你有process权限,你能看到并且杀死所有线程。否则,你只能看到并且杀死你自己的线程。
SHOW
提供关于数据库、桌子、列或服务器的信息。如果使用LIKE wild
部分,wild
字符串可以是一个使用SQL的“%”和“_”通配符的字符串。
注意:如果一个用户没有一个表的任何权限,表将不在SHOW TABLES
或mysqlshow db_name
中的输出中显示。
SHOW COLUMNS
列出在一个给定表中的列。如果列类型不同于你期望的是基于CREATE TABLE
语句的那样,注意,MySQL有时改变列类型。见。
行存储格式 (固定, 动态, 或压缩) |
已分配但未使用了字节数 |
数据文件最后更新的时间 |
最后对表运行一个检查的时间 |
当创造表时,使用的注释 (或为什么MySQL不能存取表信息的一些信息)。 |
列出一张表的列或索引。
0,如果索引不能包含重复。 |
索引中的列顺序号, 从 1 开始。 |
列怎样在索引中被排序。在MySQL中,这可以有值A (升序) 或NULL (不排序)。
|
索引中唯一值的数量。这可通过运行isamchk -a 更改.
|
如果列只是部分被索引,索引字符的数量。NULL ,如果整个键被索引。
|
上面列出的状态变量有下列含义:
由于客户没有正确关闭连接已经死掉,已经放弃的连接数量。 |
尝试已经失败的MySQL服务器的连接的次数。 |
试图连接MySQL服务器的次数。 |
当执行语句时,已经被创造了的隐含临时表的数量。 |
正在使用的延迟插入处理器线程的数量。 |
用INSERT DELAYED 写入的发生某些错误(可能重复键值 )的行数。
|
执行FLUSH 命令的次数。
|
请求从一张表中删除行的次数。 |
请求读入表中第一行的次数。 |
请求读入基于一个键的一行的次数。 |
请求读入基于一个固定位置的一行的次数。 |
请求更新表中一行的次数。 |
请求向表中插入一行的次数。 |
用于关键字缓存的块的数量。 |
请求从缓存读入一个键值的次数。 |
从磁盘物理读入一个键值的次数。 |
请求将一个关键字块写入缓存次数。 |
将一个键值块物理写入磁盘的次数。 |
同时使用的连接的最大数目。 |
在键缓存中已经改变但是还没被清空到磁盘上的键块。 |
在INSERT DELAY 队列中等待写入的行的数量。
|
打开流的数量(主要用于日志记载) |
发往服务器的查询的数量。 |
当前打开的连接的数量。 |
Handler_read_rnd
太大,那么你很可能有大量的查询需要MySQL扫描整个表或你有没正确使用键值的联结(join)。
SHOW VARIABLES
显示出一些MySQL系统变量的值,你也能使用mysqladmin variables
命令得到这个信息。如果缺省值不合适,你能在mysqld
启动时使用命令行选项来设置这些变量的大多数。输出类似于下面的显示,尽管格式和数字可以有点不同:
SHOW PROCESSLIST
显示哪个线程正在运行,你也能使用mysqladmin processlist
命令得到这个信息。如果你有process权限, 你能看见所有的线程,否则,你仅能看见你自己的线程。见。如果你不使用FULL
选项,那么每个查询只有头100字符被显示出来。
SHOW GRANTS FOR user
列出对一个用户必须发出以重复授权的授权命令。
当你在一条SELECT
语句前放上关键词EXPLAIN
,MySQL解释它将如何处理SELECT
,提供有关表如何联结和以什么次序联结的信息。
借助于EXPLAIN
,你可以知道你什么时候必须为表加入索引以得到一个使用索引找到记录的更快的SELECT
。你也能知道优化器是否以一个最佳次序联结表。为了强制优化器对一个SELECT
语句使用一个特定联结次序,增加一个STRAIGHT_JOIN
子句。
对于非简单的联结,EXPLAIN
为用于SELECT
语句中的每个表返回一行信息。表以他们将被读入的顺序被列出。MySQL用一边扫描多次联结的方式解决所有联结,这意味着MySQL从第一个表中读一行,然后找到在第二个表中的一个匹配行,然后在第3个表中等等。当所有的表被处理完,它输出选择的列并且回溯表列表直到找到一个表有更多的匹配行,从该表读入下一行并继续处理下一个表。
从EXPLAIN
的输出包括下面列:
possible_keys
列指出MySQL能使用哪个索引在该表中找到行。注意,该列完全独立于表的次序。这意味着在possible_keys中的某些键实际上不能以生成的表次序使用。如果该列是空的,没有相关的索引。在这种情况下,你也许能通过检验WHERE
子句看是否它引用某些列或列不是适合索引来提高你的查询性能。如果是这样,创造一个适当的索引并且在用EXPLAIN
检查查询。见。为了看清一张表有什么索引,使用SHOW
key
列显示MySQL实际决定使用的键。如果没有索引被选择,键是NULL
。
key_len
列显示MySQL决定使用的键长度。如果键是NULL
,长度是NULL
。注意这告诉我们MySQL将实际使用一个多部键值的几个部分。
ref
列显示哪个列或常数与key
一起用于从表中选择行。
rows
列显示MySQL相信它必须检验以执行查询的行数。
Extra
列包括文字Only index
,这意味着信息只用索引树中的信息检索出的。通常,这比扫描整个表要快。如果Extra
列包括文字where used
,它意味着一个WHERE
子句将被用来限制哪些行与下一个表匹配或发向客户。
不同的联结类型列在下面,以最好到最差类型的次序:
const
联结类型的一个特例。
const
表很快,因为它们只读取一次!
const
类型。它用在一个索引的所有部分被联结使用并且索引是UNIQUE
或PRIMARY KEY
。
UNIQUE
或PRIMARY KEY
(换句话说,如果联结不能基于键值选择单个行的话),使用ref
。如果被使用的键仅仅匹配一些行,该联结类型是不错的。
ref
列显示哪个索引被使用。
ALL
相同,除了只有索引树被扫描。这通常比ALL
快,因为索引文件通常比数据文件小。
const
的表,这通常不好,并且通常在所有的其他情况下很差。你通常可以通过增加更多的索引来避免ALL
,使得行能从早先的表中基于常数值或列值被检索出。
通过相乘EXPLAIN
输出的rows
行的所有值,你能得到一个关于一个联结要多好的提示。这应该粗略地告诉你MySQL必须检验多少行以执行查询。当你使用max_join_size
变量限制查询时,也用这个数字。见。
下列例子显示出一个JOIN
如何能使用EXPLAIN
提供的信息逐步被优化。
假定你有显示在下面的SELECT
语句,你使用