pla*_*men 0 mysql optimization
我收到了这个问题:
SELECT user_id
FROM basic_info
WHERE age BETWEEN 18 AND 22 AND gender = 0
ORDER BY rating
LIMIT 50
Run Code Online (Sandbox Code Playgroud)
该表看起来像(它包含大约700k行):
CREATE TABLE IF NOT EXISTS `basic_info` (
`user_id` mediumint(8) unsigned NOT NULL auto_increment,
`gender` tinyint(1) unsigned NOT NULL default '0',
`age` tinyint(2) unsigned NOT NULL default '0',
`rating` smallint(5) unsigned NOT NULL default '0',
PRIMARY KEY (`user_id`),
KEY `tmp` (`gender`,`rating`),
) ENGINE=MyISAM;
Run Code Online (Sandbox Code Playgroud)
查询本身已经过优化,但它必须走大约20万行来完成他的工作.这是解释输出:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE basic_info ref tmp,age tmp 1 const 200451 Using where
Run Code Online (Sandbox Code Playgroud)
是否可以优化查询,使其不会超过200k行?
谢谢 !
有两个有用的索引可以帮助这个查询:
KEY gender_age (gender, age)- 该指数既可以满足gender=0条件,也可以满足age BETWEEN 18 AND 22.但是,因为你有一个范围的条件下在age现场,加入了rating列索引不会放弃排序的结果-因此,MySQL会选择所有匹配的行-忽略你的极限条款-做一个额外的文件排序不分.
KEY gender_rating (gender, rating) - 你已经拥有的索引; 此索引可以满足gender=0条件并检索已排序的数据rating.但是,数据库必须扫描所有元素gender=0并消除那些不在范围内的元素age BETWEEN 18 AND 22
如果上述内容对您没有帮助,则始终可以更改架构.一种这样的方法是age BETWEEN通过定义年龄组列将条件转变为相等条件; 例如,0-12岁的年龄组为1岁,年龄组为12-18岁,年龄组为2岁等.
这样,使用索引(gender, agegroup, rating)和查询WHERE gender=0 AND agegroup=3 ORDER BY rating将从索引中检索所有结果并已经排序.在这种情况下,LIMIT子句应该只从表中获取50个条目,而不是更多.
| 归档时间: |
|
| 查看次数: |
175 次 |
| 最近记录: |