mpe*_*pen 10 mysql innodb performance aggregate order-by
这是我的两个查询:
select sts_in
from sta_session
where sts_user_id=2006
AND sts_sessid!='0jitkt80gg3avere03tqk4lhi6'
order by sts_in desc limit 1;
Run Code Online (Sandbox Code Playgroud)
和
select max(sts_in)
from sta_session
where sts_user_id=2006
AND sts_sessid!='0jitkt80gg3avere03tqk4lhi6';
Run Code Online (Sandbox Code Playgroud)
作为参考,该表如下所示:
CREATE TABLE `sta_session` (
`sta_session_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`sts_sessid` varchar(255) NOT NULL COMMENT 'PHP session ID',
`sts_user_id` int(10) unsigned NOT NULL,
`sts_in` bigint(20) NOT NULL,
`sts_out` bigint(20) NOT NULL,
`sts_ip` varchar(255) NOT NULL,
`sts_browser_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`sta_session_id`),
KEY `sts_sessid` (`sts_sessid`),
KEY `sts_user_id` (`sts_user_id`),
KEY `sts_ip` (`sts_ip`),
KEY `fk_sta_browser_id` (`sts_browser_id`),
KEY `idx_last_login` (`sts_user_id`,`sts_in`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)
如果我对两个查询都运行解释,第一个(按顺序)使用我专门为此查询创建的特殊索引idx_last_login,但另一个使用sts_user_id.
MAX 查询不能利用idx_last_login吗?为什么不?
我知道它可以使用该索引,因为我可以强制使用它,但我怀疑它忽略了它的sts_in一部分而只是按用户 ID 进行搜索。
EXPLAIN,JSON 格式,便于阅读。
explain select sts_in from sta_session where sts_user_id=2006 AND sts_sessid!='0jitkt80gg3avere03tqk4lhi6' order by sts_in desc limit 1;
[{
"id": 1,
"select_type": "SIMPLE",
"table": "sta_session",
"type": "ref",
"possible_keys": "sts_sessid,sts_user_id,idx_last_login",
"key": "idx_last_login",
"key_len": "4",
"ref": "const",
"rows": 723106,
"Extra": "Using where"
}
]
explain select max(sts_in) from sta_session where sts_user_id=2006 AND sts_sessid!='0jitkt80gg3avere03tqk4lhi6';
[{
"id": 1,
"select_type": "SIMPLE",
"table": "sta_session",
"type": "ref",
"possible_keys": "sts_sessid,sts_user_id,idx_last_login",
"key": "sts_user_id",
"key_len": "4",
"ref": "const",
"rows": 723107,
"Extra": "Using where"
}
]
Run Code Online (Sandbox Code Playgroud)
这对我来说很有意义。
MySQL 查询优化器查看WHERE,GROUP BY和ORDER BY子句。
看第一个查询
select sts_in
from sta_session
where sts_user_id=2006
AND sts_sessid!='0jitkt80gg3avere03tqk4lhi6'
order by sts_in desc limit 1;
Run Code Online (Sandbox Code Playgroud)
这指数sta_session在提到最栏WHERE,GROUP BY和ORDER BY条款?idx_last_login
MySQL如何定位MAX值?
sts_user_id在idx_last_login指数2006年sts_in为sts_user_id2006年sts_sessid!='0jitkt80gg3avere03tqk4lhi6'看第二个查询
select max(sts_in)
from sta_session
where sts_user_id=2006
AND sts_sessid!='0jitkt80gg3avere03tqk4lhi6';
Run Code Online (Sandbox Code Playgroud)
这指数sta_session在提到最栏WHERE,GROUP BY和ORDER BY条款?不是idx_last_login,但是sts_user_id。
MySQL如何定位MAX值?
sts_user_id2006 年全索引范围扫描sts_in从表中聚合,比较sts_sessid<>的所有值'0jitkt80gg3avere03tqk4lhi6'由于sts_user_id和idx_last_login是重复索引(因为它们具有相同的第一列),您应该运行
ALTER TABLE sta_session DROP INDEX sts_user_id;
Run Code Online (Sandbox Code Playgroud)
有idx_last_login被选择和聚合的可能性sts_in。但是,仍然有一些遍历表。
如果你真的想积极使用索引,创建这个
ALTER TABLE sta_session ADD INDEX everything_and_the_kitchen_sink_index
(sts_user_id,sts_in,sts_sessid);
Run Code Online (Sandbox Code Playgroud)
此索引可能会被选中并且永远不必接触表,因为所有列 ( WHERE, ORDER BY, MAX()) 都在索引中。
| 归档时间: |
|
| 查看次数: |
10085 次 |
| 最近记录: |