想了解MySQLSendingdata导致查询很慢的问题详细分析的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于mysql查询缓慢原因和解决方案的相关问题,此外,我们还将为您介绍关于A2-0
想了解MySQL Sending data 导致查询很慢的问题详细分析的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于mysql查询缓慢原因和解决方案的相关问题,此外,我们还将为您介绍关于A2-04-03.MySQL DATA TYPES-MySQL CHAR Data Type、A2-04-05.MySQL DATA TYPES-A Complete Guide To MySQL DATETIME Data Type、A2-04-06.MySQL DATA TYPES-MySQL DECIMAL Data Type、A2-04-10.MySQL DATA TYPES-Mastering MySQL TIME Data Type的新知识。
本文目录一览:- MySQL Sending data 导致查询很慢的问题详细分析(mysql查询缓慢原因和解决方案)
- A2-04-03.MySQL DATA TYPES-MySQL CHAR Data Type
- A2-04-05.MySQL DATA TYPES-A Complete Guide To MySQL DATETIME Data Type
- A2-04-06.MySQL DATA TYPES-MySQL DECIMAL Data Type
- A2-04-10.MySQL DATA TYPES-Mastering MySQL TIME Data Type
MySQL Sending data 导致查询很慢的问题详细分析(mysql查询缓慢原因和解决方案)
问题分析
这两天帮忙定位一个 MySQL 查询很慢的问题,定位过程综合各种方法、理论、工具,很有代表性,分享给大家
【问题现象】
使用 sphinx 支持倒排索引,但 sphinx 从 mysql 查询源数据的时候,查询的记录数才几万条,但查询的速度非常慢,大概要 4~5 分钟左右
【处理过程】
1)explain
首先怀疑索引没有建好,于是使用 explain 查看查询计划,结果如下:
从 explain 的结果来看,整个语句的索引设计是没有问题的,除了第一个表因为业务需要进行整表扫描外,其它的表都是通过索引访问
2)show processlist;
explain 看不出问题,那到底慢在哪里呢?
于是想到了使用 show processlist 查看 sql 语句执行状态,查询结果如下:
发现很长一段时间,查询都处在 “Sending data” 状态
查询一下 “Sending data” 状态的含义,原来这个状态的名称很具有误导性,所谓的 “Sending data” 并不是单纯的发送数据,而是包括 “收集 + 发送 数据”。
这里的关键是为什么要收集数据,原因在于:mysql 使用 “索引” 完成查询结束后,mysql 得到了一堆的行 id,如果有的列并不在索引中,mysql 需要重新到 “数据行” 上将需要返回的数据读取出来返回个客户端。
3)show profile
为了进一步验证查询的时间分布,于是使用了 show profile 命令来查看详细的时间分布
首先打开配置:set profiling=on;
执行完查询后,使用 show profiles 查看 query id;
使用 show profile for query query_id 查看详细信息;
结果如下:
从结果可以看出,Sending data 的状态执行了 216s
4)排查对比
经过以上步骤,已经确定查询慢是因为大量的时间耗费在了 Sending data 状态上,结合 Sending data 的定义,将目标聚焦在查询语句的返回列上面
经过一 一排查,最后定为到一个 description 的列上,这个列的设计为:`description`varchar (8000) DEFAULT NULL COMMENT '' 游戏描述 '',
于是采取了对比的方法,看看 “不返回 description 的结果” 如何。show profile 的结果如下:
可以看出,不返回 description 的时候,查询时间只需要 15s,返回的时候,需要 216s,两者相差 15 倍
【原理研究】
至此问题已经明确,但原理上我们还需要继续探究。
这篇淘宝的文章很好的解释了相关原理:innodb 使用大字段 text,blob 的一些优化建议
这里的关键信息是:当 Innodb 的存储格式是 ROW_FORMAT=COMPACT
(or ROW_FORMAT=REDUNDANT
) 的时候,Innodb 只会存储前 768 字节的长度,剩余的数据存放到 “溢出页” 中。
我们使用 show table status 来查看表的相关信息:
可以看到,平均一行大约 1.5K,也就说大约 1/10 行会使用 “溢出存储”,一旦采用了这种方式存储,返回数据的时候本来是顺序读取的数据,就变成了随机读取了,所以导致性能急剧下降。
另外,在测试过程中还发现,无论这条语句执行多少次,甚至将整个表 select * 几次,语句的执行速度都没有明显变化。这个表的数据和索引加起来才 150M 左右,而整个 Innodb buffer pool 有 5G,缓存整张表绰绰有余,如果缓存了溢出页,性能应该大幅提高才对。
但实测结果却并没有提高,因此从这个测试可以推论 Innodb 并没有将溢出页(overflow page)缓存到内存里面。
这样的设计也是符合逻辑的,因为 overflow page 本来就是存放大数据的,如果也放在缓存里面,就会出现一次大数据列(blob、text、varchar)查询,可能就将所有的缓存都更新了,这样会导致其它普通的查询性能急剧下降。
【解决方法】
找到了问题的根本原因,解决方法也就不难了。有几种方法:
1)查询时去掉 description 的查询,但这受限于业务的实现,可能需要业务做较大调整
2)表结构优化,将 descripion 拆分到另外的表,这个改动较大,需要已有业务配合修改,且如果业务还是要继续查询这个 description 的信息,则优化后的性能也不会有很大提升。
我的问题
我遇到的问题是,在我的表 taobao_newadd
其中 pdata 的字段,数据较大,每条大概 200KiB,导致了查询语句:
$list = $conn->fetchAll("select id,taobaoid,pdata from taobao_newadd where type = ''attr''");
非常慢,经 show processlist; 查看,发现很长一段时间,查询都处在 “Sending data” 状态。如果语句把 pdata 去掉其实速度也是挺快的。
解决思路
1)建索引
经查看(explain),已经建好了,跳过;
2)分表
把 pdata 单独分出去,考虑了好久,数据表才 16G,并且 pdata 也是需要经常查询的,暂不考虑
3)还是调整 sql 语句逻辑,优化 sql 语句
原因:一下子查询所有的 pdata,返回的数据肯定很大了。而当前,并不一定非得一个语句查询所有。
解决:
$list = $conn->fetchAll("select id,taobaoid,pdata from taobao_newadd where type = ''attr''");
foreach($list as $row){
//doing pdata ......
}
改成
$ids= $conn->fetchAll("select id from taobao_newadd where type = ''attr''");
foreach($ids as $id){
$row= $conn->fetchRow("select taobaoid,pdata from taobao_newadd where id=".$id[''id'']);
//doing pdata .....
}
备注:参考 nosql 的思想,把查询的粒度变小点。为了查询速度,稍稍多写点代码也是可以的。
参考:http://blog.csdn.net/yunhua_lee/article/details/8573621
A2-04-03.MySQL DATA TYPES-MySQL CHAR Data Type
转载自:http://www.mysqltutorial.org/mysql-char-data-type/
MySQL CHAR Data Type
Summary: in this tutorial, you will learn about MySQL CHAR data type and how to apply it in your database table design.
Introduction to MySQL CHAR data type
The CHAR
data type is a fixed-length character type in MySQL. We often declare the CHAR
type with a length that specifies the maximum number of characters that we want to store. For example, CHAR(20)
can hold up to 20 characters.
If the data that you want to store is a fixed size, you should use the CHAR
data type. You’ll get a better performance in comparison with VARCHAR
in this case.
The length of the CHAR
data type can be any value from 0 to 255. When you store a CHAR
value, MySQL pads its value with spaces to the length that you declared.
When you query the CHAR
value, MySQL removes the trailing spaces.
Note that MySQL will not remove the trailing spaces if you enable the PAD_CHAR_TO_FULL_LENGTHSQL mode.
The following statement creates a table with a CHAR
column.
1
2
3
|
CREATE TABLE mysql_char_test (
status CHAR(3)
);
|
The status column has the CHAR
data type. It can hold up to 3 characters.
Now, we insert 2 rows into the mysql_char_test
table.
1
2
|
INSERT INTO mysql_char_test(status)
VALUES(''Yes''),(''No'');
|
We use the length function to get the length of each CHAR value.
1
2
3
4
|
SELECT
status, LENGTH(status)
FROM
mysql_char_test;
|
The following statement inserts a CHAR
value with the leading and trailing spaces.
1
2
|
INSERT INTO mysql_char_test(status)
VALUES('' Y '');
|
However, when we retrieve the value, MySQL removes the trailing space.
1
2
3
4
|
SELECT
status, LENGTH(status)
FROM
mysql_char_test;
|
Comparing MySQL CHAR values
When storing or comparing the CHAR
values, MySQL uses the character set collation assigned to the column.
MySQL does not consider trailing spaces when comparing CHAR
values using the comparison operator such as =, <>, >, <, etc.
Notice that the LIKE operator does consider the trailing spaces when you do pattern matching with CHAR
values.
In the previous example, we stored the value Y with both leading and trailing spaces. However, when we execute the following query:
1
2
3
4
5
6
|
SELECT
*
FROM
mysql_char_test
WHERE
status = ''Y'';
|
MySQL returns no row because it does not consider the trailing space. To match with the ‘ Y ‘, we need to remove the trailing space as follows:
1
2
3
4
5
6
|
SELECT
*
FROM
mysql_char_test
WHERE
status = '' Y'';
|
MySQL CHAR and UNIQUE index
If the CHAR
column has a UNIQUE
index and you insert a value that is different from an existing value in a number of trailing spaces, MySQL will reject the changes because of duplicate-key error.
See the following example.
First, create a unique index for the status
column of the mysql_char_test
table.
1
|
CREATE UNIQUE INDEX uidx_status ON mysql_char_test(status);
|
Second, insert a new row into the mysql_char_test
table.
1
2
|
INSERT INTO mysql_char_test(status)
VALUES(''N'');
|
Third, insert the following value will cause a duplicate-key error.
1
2
|
INSERT INTO mysql_char_test(status)
VALUES(''N '');
|
1
|
Error Code: 1062. Duplicate entry ''N'' for key ''uidx_status''
|
In this tutorial, we have introduced you to the MySQL CHAR data type and its features. Now, you should have a good understanding of the CHAR data type to apply it in your database design.
A2-04-05.MySQL DATA TYPES-A Complete Guide To MySQL DATETIME Data Type
转载自:http://www.mysqltutorial.org/mysql-datetime/
A Complete Guide To MySQL DATETIME Data Type
Summary: in this tutorial, you will learn about MySQL DATETIME
data type and how to use some handy functions for manipulating DATETIME
effectively.
Introduction to MySQL DATETIME data type
You use MySQL DATETIME
to store a value that contains both date and time. When you query data from a DATETIME
column, MySQL displays the DATETIME
value in the following format:
1
|
YYYY
-MM-DD HH:MM:SS
|
By default, DATETIME
values range from 1000-01-01 00:00:00
to 9999-12-31 23:59:59
.
A DATETIME
value uses 5 bytes for storage. In addition, a DATETIME
value can include a trailing fractional second up to microseconds with the format YYYY-MM-DD HH:MM:SS[.fraction]
e.g., 2015-12-20 10:01:00.999999
. When including the fractional second precision, DATETIME
values require more storage as illustrated in the following table:
Fractional Seconds Precision | Storage (Bytes) |
---|---|
0 | 0 |
1, 2 | 1 |
3, 4 | 2 |
5, 6 | 3 |
For example, 2015-12-20 10:01:00.999999
requires 8 bytes, 5 bytes for 2015-12-20 10:01:00
and 3 bytes for .999999
while 2015-12-20 10:01:00.9
requires only 6 bytes, 1 byte for the fractional second precision.
Note that before MySQL 5.6.4, DATETIME
values requires 8 bytes storage instead of 5 bytes.
MySQL DATETIME vs. TIMESTAMP
MySQL provides another temporal data type that is similar to the DATETIME
called TIMESTAMP
.
The TIMESTAMP
requires 4 bytes while DATETIME
requires 5 bytes. Both TIMESTAMP
and DATETIME
require additional bytes for fractional seconds precision.
TIMESTAMP
values range from 1970-01-01 00:00:01 UTC
to 2038-01-19 03:14:07 UTC
. If you want to store temporal values that are beyond 2038, you should use DATETIME
instead of TIMESTAMP
.
MySQL stores TIMESTAMP
in UTC value. However, MySQL stores the DATETIME
value as is without timezone. Let’s see the following example.
First, set the timezone of the current connection to +00:00
.
1
|
SET time_zone = ''+00:00'';
|
Next, create a table named timestamp_n_datetime
that consists of two columns: ts
and dt
with TIMESTAMP
and DATETIME
types using the following statement.
1
2
3
4
5
|
CREATE TABLE timestamp_n_datetime (
id INT AUTO_INCREMENT PRIMARY KEY,
ts TIMESTAMP,
dt DATETIME
);
|
Then, insert the current date and time into both ts
and dt
columns of the timestamp_n_datetime
table,
1
2
|
INSERT INTO timestamp_n_datetime(ts,dt)
VALUES(NOW(),NOW());
|
After that, query data from the timestamp_n_datetime
table.
1
2
3
4
5
|
SELECT
ts,
dt
FROM
timestamp_n_datetime;
|
Both values in DATETIME
and TIMESTAMP
columns are the same.
Finally, set the connection’s time zone to +03:00
and query data from the timestamp_n_datetime
table again.
1
2
3
4
5
6
7
|
SET time_zone = ''+03:00'';
SELECT
ts,
dt
FROM
timestamp_n_datetime;
|
As you can see, the value in the TIMESTAMP
column is different. This is because the TIMESTAMP
column stores the date and time value in UTC when we changed the time zone, the value of the TIMESTAMP
column is adjusted according to the new time zone.
It means that if you use the TIMESTAMP
data to store date and time values, you should take a serious consideration when you move your database to a server located in a different time zone.
MySQL DATETIME functions
The following statement sets the variable @dt
to the current date and time using the NOW()
function.
1
|
SET @dt = NOW();
|
To query the value of the @dt
variable, you use the following SELECT
statement:
1
|
SELECT @dt;
|
MySQL DATE function
To extract the date portion from a DATETIME
value, you use the DATE
function as follows:
1
|
SELECT DATE(@dt);
|
This function is very useful in case you want to query data based on a date but the data stored in the column is based on both date and time.
Let’s see the following example.
1
2
3
4
5
6
7
|
CREATE TABLE test_dt (
id INT AUTO_INCREMENT PRIMARY KEY,
created_at DATETIME
);
INSERT INTO test_dt(created_at)
VALUES(''2015-11-05 14:29:36'');
|
Suppose you want to know which row created on 2015-11-05
, you use the following query:
1
2
3
4
5
6
|
SELECT
*
FROM
test_dt
WHERE
created_at = ''2015-11-05'';
|
It returns no rows.
This is because the created_at
column contains not only date but also time. To correct it, you use the DATE
function as follows:
1
2
3
4
5
6
|
SELECT
*
FROM
test_dt
WHERE
DATE(created_at) = ''2015-11-05'';
|
It returns one row as expected. In case the table has many rows, MySQL has to perform a full table scan to locate the rows that match the condition.
MySQL TIME function
To extract the time portion from a DATETIME
value, you use the TIME
function as the following statement:
1
|
SELECT TIME(@dt);
|
MySQL YEAR, QUARTER, MONTH, WEEK, DAY, HOUR, MINUTE and SECOND functions
To get the year, quarter, month, week, day, hour, minute, and second from a DATETIME
value, you use the functions as shown in the following statement:
1
2
3
4
5
6
7
8
9
|
SELECT
HOUR(@dt),
MINUTE(@dt),
SECOND(@dt),
DAY(@dt),
WEEK(@dt),
MONTH(@dt),
QUARTER(@dt),
YEAR(@dt);
|
MySQL DATE_FORMAT function
To format a DATETIME
value, you use the DATE_FORMAT
function. For example, the following statement formats a DATETIME
value based on the %H:%i:%s - %W %M %Y
format:
1
|
SELECT DATE_FORMAT(@dt, ''%H:%i:%s - %W %M %Y'');
|
MySQL DATE_ADD function
To add an interval to a DATETIME
value, you use DATE_ADD
function as follows:
1
2
3
4
5
6
7
8
|
SELECT @dt start,
DATE_ADD(@dt, INTERVAL 1 SECOND) ''1 second later'',
DATE_ADD(@dt, INTERVAL 1 MINUTE) ''1 minute later'',
DATE_ADD(@dt, INTERVAL 1 HOUR) ''1 hour later'',
DATE_ADD(@dt, INTERVAL 1 DAY) ''1 day later'',
DATE_ADD(@dt, INTERVAL 1 WEEK) ''1 week later'',
DATE_ADD(@dt, INTERVAL 1 MONTH) ''1 month later'',
DATE_ADD(@dt, INTERVAL 1 YEAR) ''1 year later'';
|
MySQL DATE_SUB function
To subtract an interval from a DATETIME
value, you use DATE_SUB
function as follows:
1
2
3
4
5
6
7
8
|
SELECT @dt start,
DATE_SUB(@dt, INTERVAL 1 SECOND) ''1 second before'',
DATE_SUB(@dt, INTERVAL 1 MINUTE) ''1 minute before'',
DATE_SUB(@dt, INTERVAL 1 HOUR) ''1 hour before'',
DATE_SUB(@dt, INTERVAL 1 DAY) ''1 day before'',
DATE_SUB(@dt, INTERVAL 1 WEEK) ''1 week before'',
DATE_SUB(@dt, INTERVAL 1 MONTH) ''1 month before'',
DATE_SUB(@dt, INTERVAL 1 YEAR) ''1 year before'';
|
MySQL DATE_DIFF function
To calculate a difference in days between two DATETIME
values, you use the DATEDIFF
function. Notice that the DATEDIFF
function only considers the date part of a DATETIME
value in the calculation.
See the following example.
First, create a table named datediff_test
that has one column whose data type is DATETIME
.
1
2
3
|
CREATE TABLE datediff_test (
dt DATETIME
);
|
Second, insert some rows into the datediff_test
table.
1
2
3
4
5
6
7
8
|
INSERT INTO datediff_test(dt)
VALUES(''2010-04-30 07:27:39''),
(''2010-05-17 22:52:21''),
(''2010-05-18 01:19:10''),
(''2010-05-22 14:17:16''),
(''2010-05-26 03:26:56''),
(''2010-06-10 04:44:38''),
(''2010-06-13 13:55:53'');
|
Third, use the DATEDIFF
function to compare the current date and time with the value in each row of the datediff_test
table.
1
2
3
4
5
|
SELECT
dt,
DATEDIFF(NOW(), dt)
FROM
datediff_test;
|
In this tutorial, you have learned about MySQL DATETIME
data type and some useful DATETIME
functions.
A2-04-06.MySQL DATA TYPES-MySQL DECIMAL Data Type
转载自:http://www.mysqltutorial.org/mysql-decimal/
MySQL DECIMAL Data Type
Summary: in this tutorial, we will introduce you to the MySQL DECIMAL data type and how to use it effectively in your database table.
Introduction to MySQL DECIMAL data type
The MySQL DECIMAL data type is used to store exact numeric values in the database. We often use the DECIMAL data type for columns that preserve exact precision e.g., money data in accounting systems.
To define a column whose data type is DECIMAL you use the following syntax:
1
|
column_name
DECIMAL(P,D);
|
In the syntax above:
- P is the precision that represents the number of significant digits. The range of P is 1 to 65.
- D is the scale that that represents the number of digits after the decimal point. The range of D is 0 and 30. MySQL requires that D is less than or equal to (<=) P.
The DECIMAL(P,D)
means that the column can store up to P digits with D decimals. The actual range of the decimal column depends on the precision and scale.
Besides the DECIMAL
keyword, you can also use DEC
, FIXED
, or NUMERIC
because they are synonyms for DECIMAL
.
Like the INT data type, the DECIMAL
type also has UNSIGNED
and ZEROFILL
attributes. If we use the UNSIGNED
attribute, the column with DECIMAL UNSIGNED
will not accept negative values.
In case we use ZEROFILL
, MySQL will pad the display value by 0 up to display width specified by the column definition. In addition, if we use ZERO FILL
for the DECIMAL
column, MySQL will add the UNSIGNED
attribute to the column automatically.
The following example defines amount column with DECIMAL
data type.
1
|
amount
DECIMAL(6,2);
|
In this example, the amount column can store 6 digits with 2 decimal places; therefore, the range of the amount column is from 9999.99 to -9999.99.
MySQL allows us to use the following syntax:
1
|
column_name
DECIMAL(P);
|
This is equivalent to:
1
|
column_name
DECIMAL(P,0);
|
In this case, the column contains no fractional part or decimal point.
In addition, we can even use the following syntax.
1
|
column_name
DECIMAL;
|
The default value of P is 10 in this case.
MySQL DECIMAL storage
MySQL assigns the storage for integer and fractional parts separately. MySQL uses binary format to store the DECIMAL
values. It packs 9 digits into 4 bytes.
For each part, it takes 4 bytes to store each multiple of 9 digits. The storage required for leftover digits is illustrated in the following table:
Leftover Digits | Bytes |
---|---|
0 | 0 |
1–2 | 1 |
3–4 | 2 |
5–6 | 3 |
7–9 | 4 |
For example, DECIMAL(19,9)
has 9 digits for the fractional part and 19-9 = 10 digits for integer part. The fractional part requires 4 bytes. The integer part requires 4 bytes for the first 9 digits, for 1 leftover digit, it requires 1 more byte. In total, the DECIMAL(19,9)
column requires 9 bytes.
MySQL DECIMAL data type and monetary data
We often use the DECIMAL
data type for monetary data such as prices, salary, account balances, etc. If you design a database that handle the monetary data, the following syntax should be OK.
1
|
amount
DECIMAL(19,2);
|
However, if you want to comply with Generally Accepted Accounting Principles (GAAP) rules, the monetary column must have at least 4 decimal places to make sure that the rounding value does not exceed $0.01. In this case, you should define the column with 4 decimal places as follows:
1
|
amount
DECIMAL(19,4);
|
MySQL DECIMAL data type example
First, create a new table named materials
with three columns: id, description, and cost.
1
2
3
4
5
|
CREATE TABLE materials (
id INT AUTO_INCREMENT PRIMARY KEY,
description VARCHAR(255),
cost DECIMAL(19 , 4 ) NOT NULL
);
|
Second, insert data into the materials
table.
1
2
|
INSERT INTO materials(description,cost)
VALUES(''Bicycle'', 500.34),(''Seat'',10.23),(''Break'',5.21);
|
Third, query data from the materials
table.
1
2
3
4
|
SELECT
*
FROM
materials;
|
Fourth, change the cost column to include the ZEROFILL
attribute.
1
2
|
ALTER TABLE materials
MODIFY cost DECIMAL(19,4) zerofill;
|
Fifth, query the materials table again.
1
2
3
4
|
SELECT
*
FROM
materials;
|
As you see, we have many zeros padded in the output values.
In this tutorial, we have shown gave you detailed information on MySQL DECIMAL data type and shown you how to apply it to the columns that store exact numeric data such as financial data.
A2-04-10.MySQL DATA TYPES-Mastering MySQL TIME Data Type
转载自:http://www.mysqltutorial.org/mysql-time/
Mastering MySQL TIME Data Type
Summary: in this tutorial, we will introduce you to the MySQL TIME
data type and show you useful temporal functions to manipulate time data effectively.
Introduction to MySQL TIME data type
MySQL uses the ''HH:MM:SS''
format for querying and displaying a time value that represents a time of day, which is within 24 hours. To represent a time interval between two events, MySQL uses the ''HHH:MM:SS''
format, which is larger than 24 hours.
To define a TIME
column, you use the following syntax:
1
|
column_name
TIME;
|
For example, the following snippet defines a column named start_at
with TIME
data type.
1
|
start_at
TIME;
|
A TIME
value ranges from -838:59:59
to 838:59:59
. In addition, a TIME
value can have fractional seconds part that is up to microseconds precision (6 digits). To define a column whose data type is TIME
with a fractional second precision part, you use the following syntax:
1
|
column_name
TIME(N);
|
N is an integer that represents the fractional part, which is up to 6 digits.
The following snippet defines a column with TIME
data type including 3 digits of fractional seconds.
1
|
begin_at
TIME(3);
|
A TIME
value takes 3 bytes for storage. In case a TIME
value includes fractional second precision, it will take additional bytes based on the number of digits of the fractional second precision. The following table illustrates the storage required for fractional second precision.
Fractional Second Precision | Storage (BYTES) |
0 | 0 |
1, 2 | 1 |
3, 4 | 2 |
5, 6 | 3 |
For example, TIME
and TIME(0)
takes 3 bytes. TIME(1)
and TIME(2)
takes 4 bytes (3 + 1); TIME(3)
and TIME(6)
take 5 and 6 bytes.
MySQL TIME data type example
Let’s take a look at an example of using the TIME
data type for columns in a table.
First, create a new table named tests
that consists of four columns: id
, name
, start_at
, and end_at
. The data types of the start_at
and end_at
columns are TIME
.
1
2
3
4
5
6
|
CREATE TABLE tests (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
start_at TIME,
end_at TIME
);
|
Second, insert a row into the tests
table.
1
2
|
INSERT INTO tests(name,start_at,end_at)
VALUES(''Test 1'', ''08:00:00'',''10:00:00'');
|
Third, query data from the tests
table.
1
2
3
4
|
SELECT
name, start_at, end_at
FROM
tests;
|
Notice that we use ''HH:MM:SS''
as the literal time value in the INSERT
statement. Let’s examine all the valid time literals that MySQL can recognize.
MySQL TIME literals
MySQL recognizes various time formats besides the ''HH:MM:SS''
format that we mentioned earlier.
MySQL allows you to use the ''HHMMSS''
format without delimiter ( : ) to represent time value. For example, ''08:30:00''
and ''10:15:00''
can be rewritten as ''083000''
and ''101500''
.
1
2
|
INSERT INTO tests(name,start_at,end_at)
VALUES(''Test 2'',''083000'',''101500'');
|
However, 108000
is not a valid time value because 80
does not represent the correct minute. In this case, MySQL will raise an error if you try to insert an invalid time value into a table.
1
2
|
INSERT INTO tests(name,start_at,end_at)
VALUES(''Test invalid'',''083000'',''108000'');
|
MySQL issued the following error message after executing the above statement.
1
|
Error
Code: 1292. Incorrect time value: ''108000'' for column ''end_at'' at row 1
|
In addition to the string format, MySQL accepts the HHMMSS
as a number that represents a time value. You can also use SS
, MMSS
. For example, instead of using ''082000''
, you can use 082000
as follows:
1
2
|
INSERT INTO tests(name,start_at,end_at)
VALUES(''Test 3'',082000,102000);
|
For the time interval, you can use the ''D HH:MM:SS''
format where D
represents days with a range from 0 to 34. A more flexible syntax is ''HH:MM''
, ''D HH:MM''
, ''D HH''
, or ''SS''
.
If you use the delimiter:, you can use 1 digit to represent hours, minutes, or seconds. For example, 9:5:0
can be used instead of ''09:05:00''
.
1
2
|
INSERT INTO tests(name,start_at,end_at)
VALUES(''Test 4'',''9:5:0'',100500);
|
Useful MySQL TIME functions
MySQL provides several useful temporal functions for manipulating TIME
data.
Getting to know the current time
To get the current time of the database server, you use the CURRENT_TIME
function. The CURRENT_TIME
function returns the current time value as a string ( ''HH:MM:SS''
) or a numeric value ( HHMMSS
) depending on the context where the function is used.
The following statements illustrate the CURRENT_TIME
function in both string and numeric contexts:
1
2
3
|
SELECT
CURRENT_TIME() AS string_now,
CURRENT_TIME() + 0 AS numeric_now;
|
Adding and Subtracting time from a TIME value
To add a TIME
value to another TIME
value, you use the ADDTIME
function. To subtract a TIME
value from another TIME
value, you use the SUBTIME
function.
The following statement adds and subtracts 2 hours 30 minutes to and from the current time.
1
2
3
4
|
SELECT
CURRENT_TIME(),
ADDTIME(CURRENT_TIME(), 023000),
SUBTIME(CURRENT_TIME(), 023000);
|
In addition, you can use the TIMEDIFF()
function to get a difference between two TIME
values.
1
2
3
4
|
SELECT
TIMEDIFF(end_at, start_at)
FROM
tests;
|
Formatting MySQL TIME values
Although MySQL uses ''HH:MM:SS''
when retrieving and displaying the a TIME
value, you can display the TIME
value in your preferred way using the TIME_FORMAT
function.
The TIME_FORMAT
function is like the DATE_FORMAT
function except that the TIME_FORMAT
function is used to format a TIME
value only.
See the following example.
1
2
3
4
5
6
|
SELECT
name,
TIME_FORMAT(start_at, ''%h:%i %p'') start_at,
TIME_FORMAT(end_at, ''%h:%i %p'') end_at
FROM
tests;
|
In the time format string above:
-
%h
means two-digit hours from 0 to 12. -
%i
means two-digit minutes from 0 to 60. -
%p
means AM or PM.
Extracting hour, minute, and second from a TIME value
To extract the hour, minute, and second from a TIME
value, you use HOUR
, MINUTE
, and SECOND
functions as follows:
Getting UTC time value
To get the UTC time, you use UTC_TIME
function as follows:
1
2
3
|
SELECT
CURRENT_TIME(),
UTC_TIME();
|
In this tutorial, we have been covered a lot about MySQL TIME
data type and some commonly used temporal functions for manipulating TIME
values.
关于MySQL Sending data 导致查询很慢的问题详细分析和mysql查询缓慢原因和解决方案的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于A2-04-03.MySQL DATA TYPES-MySQL CHAR Data Type、A2-04-05.MySQL DATA TYPES-A Complete Guide To MySQL DATETIME Data Type、A2-04-06.MySQL DATA TYPES-MySQL DECIMAL Data Type、A2-04-10.MySQL DATA TYPES-Mastering MySQL TIME Data Type等相关内容,可以在本站寻找。
本文标签: