如何使用 MySql 的 where 和 group by
How using where and group by for MySql
我的数据库中有一个 table:
CREATE TABLE `yapial` (
`user_id` int(11) NOT NULL,
`username` varchar(255) DEFAULT NULL,
`first_name` varchar(50) DEFAULT NULL,
`last_name` varchar(50) DEFAULT NULL,
`gender` varchar(10) DEFAULT NULL,
`password` varchar(50) DEFAULT NULL,
`status` tinyint(10) DEFAULT NULL,
`date` datetime NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
status 和 date 列索引。我运行sql代码:
select status, count(*) from user_details group by status
并成功 运行ning 0.34 毫秒。但我想添加日期限制 =>
select date, status, count(*) from user_details
where date between '2017-01-25 18:13:50' and '2017-01-29 18:13:50'
group by status
成功 运行宁 6.52 秒。时间限制太高了。我想减少时间运行ning。我该如何改进?
耗时 0.34 毫秒的查询可能是从 MySQL query cache 获取结果的。查询不太可能这么快。
我认为最好的优化是如果你有一个 two-column 索引。有两种可能:
alter table user_details
add key (status, date),
add key (date, status);
如果使用第一个索引,它会做一个 index-scan 但它会避免临时 table:
explain select sql_no_cache date, status, count(*)
from user_details use index (status)
where date between '2017-01-25 18:13:50' and '2017-01-29 18:13:50'
group by status\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user_details
partitions: NULL
type: index
possible_keys: date,status
key: status
key_len: 7
ref: NULL
rows: 3
filtered: 33.33
Extra: Using where; Using index
如果使用第二个索引,它会使用该索引进行范围查找,按日期范围匹配行,但会导致临时table.
root@localhost [test] > explain select sql_no_cache date, status, count(*)
from user_details use index (date)
where date between '2017-01-25 18:13:50' and '2017-01-29 18:13:50'
group by status\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user_details
partitions: NULL
type: range
possible_keys: date,status
key: date
key_len: 5
ref: NULL
rows: 1
filtered: 100.00
Extra: Using where; Using index; Using temporary; Using filesort
哪个索引最好取决于有多少行符合条件。
我的数据库中有一个 table:
CREATE TABLE `yapial` (
`user_id` int(11) NOT NULL,
`username` varchar(255) DEFAULT NULL,
`first_name` varchar(50) DEFAULT NULL,
`last_name` varchar(50) DEFAULT NULL,
`gender` varchar(10) DEFAULT NULL,
`password` varchar(50) DEFAULT NULL,
`status` tinyint(10) DEFAULT NULL,
`date` datetime NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
status 和 date 列索引。我运行sql代码:
select status, count(*) from user_details group by status
并成功 运行ning 0.34 毫秒。但我想添加日期限制 =>
select date, status, count(*) from user_details
where date between '2017-01-25 18:13:50' and '2017-01-29 18:13:50'
group by status
成功 运行宁 6.52 秒。时间限制太高了。我想减少时间运行ning。我该如何改进?
耗时 0.34 毫秒的查询可能是从 MySQL query cache 获取结果的。查询不太可能这么快。
我认为最好的优化是如果你有一个 two-column 索引。有两种可能:
alter table user_details
add key (status, date),
add key (date, status);
如果使用第一个索引,它会做一个 index-scan 但它会避免临时 table:
explain select sql_no_cache date, status, count(*)
from user_details use index (status)
where date between '2017-01-25 18:13:50' and '2017-01-29 18:13:50'
group by status\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user_details
partitions: NULL
type: index
possible_keys: date,status
key: status
key_len: 7
ref: NULL
rows: 3
filtered: 33.33
Extra: Using where; Using index
如果使用第二个索引,它会使用该索引进行范围查找,按日期范围匹配行,但会导致临时table.
root@localhost [test] > explain select sql_no_cache date, status, count(*)
from user_details use index (date)
where date between '2017-01-25 18:13:50' and '2017-01-29 18:13:50'
group by status\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user_details
partitions: NULL
type: range
possible_keys: date,status
key: date
key_len: 5
ref: NULL
rows: 1
filtered: 100.00
Extra: Using where; Using index; Using temporary; Using filesort
哪个索引最好取决于有多少行符合条件。