mysql索引问题,现在关于where条件有status、cate_id、price三个,ORDER BY分别可能likes、hits、id排序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql索引问题,现在关于where条件有status、cate_id、price三个,ORDER BY分别可能likes、hits、id排序相关的知识,希望对你有一定的参考价值。

还有一个情况,条件只有两个status、cate_id,也就是现在查询有这么几种可能:
1、select * from XXX where status=? and cate_id=? ORDER BY likes DESC
2、select * from XXX where status=? and cate_id=? ORDER BY hits DESC
3、select * from XXX where status=? and cate_id=? ORDER BY id DESC
4、select * from XXX where status=? and cate_id=? and price>? ORDER BY likes DESC
5、select * from XXX where status=? and cate_id=? and price>? ORDER BY hits DESC
6、select * from XXX where status=? and cate_id=? and price>? ORDER BY id DESC
有这么6种查询,而且ORDER BY 中的id 是主键,我用EXPLAIN查看是KEY采用的是PRIMARY
请问,像这样的查询,mysql可以采用什么样的索引呢?因为发现如果查询10万以上,时间会很久了,是建立多个组合索引吗?这样索引的数据量很大,但不建立的话,一个大分类下的数据会很多,这样容易挂掉,有什么好的办法吗?索引方面的,谢谢
说明:status这个只有两个值(0和1)、cate_id会比较多些,price价格是个区间
ORDER BY id时 命中的非常低

建议
status建立位图索引,具体的可以百度一下
cate_id单独建立一个普通索引
cate_id和price建立联合索引

具体的还得EXPLAIN来分析一下,有的时候自己预测的跟语句运行的结果不太一样呢,哎,这个很愁人
-------------补充-----------
有EXPLAIN的分析数据吗?追问

位图索引mysql不支持吧?
where条件status、cate_id、price三个外,还有ORDER BY(likes、hits、id三个中的一个)
这个有什么处理方式吗?
EXPLAIN数据今天暂时清理了数据,没有,下次补上看看

参考技术A order by xx:xx要在where里出现order by xx才会使用索引。
如果只select 索引 的话,order by 也会效率。

多explain吧、避免top sql追问

如果只select 索引 的话,order by 也会效率。---这个也会效率是什么意思?

Mysql系列—— 索引下推优化

索引条件下推(ICP)是对MySQL使用索引从表中检索行的情况的优化。如果没有ICP,存储引擎会遍历索引以查找基表中的行,并将它们返回给MySQL服务器,该服务器会评估WHERE行的条件。启用ICP后,如果WHERE只使用索引中的列来评估部分 条件,MySQL服务器会推送这部分内容。WHERE条件下到存储引擎。然后,存储引擎通过使用索引条目来评估推送的索引条件,并且仅当满足该条件时才从表中读取行。ICP可以减少存储引擎必须访问基表的次数以及MySQL服务器必须访问存储引擎的次数。

指数条件下推优化的适用性受以下条件限制:

  • ICP用于 range, ref, eq_ref,和 ref_or_null访问方法时,有必要访问完整的表行。

  • ICP可用于表InnoDB 和MyISAM表,包括分区InnoDB和 MyISAM表。

  • 对于InnoDB表,ICP仅用于二级索引。ICP的目标是减少全行读取的数量,从而减少I / O操作。对于 InnoDB聚簇索引,已将完整记录读入InnoDB 缓冲区。在这种情况下使用ICP不会降低I / O.

  • 在虚拟生成列上创建的二级索引不支持ICP。InnoDB 支持虚拟生成列上的二级索引。

  • 引用子查询的条件无法下推。

  • 引用存储函数的条件无法下推。存储引擎无法调用存储的函数。

  • 触发条件无法下推。(有关触发条件的信息,请参见 第8.2.2.4节“使用EXISTS策略优化子查询”。)

要了解此优化的工作原理,请首先考虑在不使用索引条件下推时索引扫描的进度:

获取下一行,首先读取索引元组,然后使用索引元组找到并读取整个表行。

测试WHERE适用于此表的条件部分。根据测试结果接受或拒绝该行。

使用索引条件下推,扫描会像这样进行:

获取下一行的索引元组(但不是完整的表行)。

测试WHERE适用于此表的条件部分,并且只能使用索引列进行检查。如果不满足条件,则继续下一行的索引元组。

如果满足条件,请使用索引元组来查找并读取整个表行。

测试WHERE 适用于此表的条件的剩余部分。根据测试结果接受或拒绝该行。

EXPLAIN使用“索引条件下推”时,输出显示 Using index condition在 Extra列中。它没有显示,Using index 因为当必须读取完整的表行时,这不适用。

假设一个表包含有关人员及其地址的信息,并且该表的索引定义为 INDEX (zipcode, lastname, firstname)。如果我们知道一个人的zipcode价值但不确定姓氏,我们可以这样搜索:

SELECT * FROM people
  WHERE zipcode=‘95054‘
  AND lastname LIKE ‘%etrunia%‘
  AND address LIKE ‘%Main Street%‘;

MySQL可以使用索引来扫描人 zipcode=‘95054‘。第二部分(lastname LIKE ‘%etrunia%‘)不能用于限制必须扫描的行数,因此,如果没有Index Condition Pushdown,此查询必须为所有拥有的人检索完整的表行 zipcode=‘95054‘。

使用索引条件下推,MySQL lastname LIKE ‘%etrunia%‘在读取整个表行之前检查该 部分。这样可以避免读取与索引元组相对应的完整行,这些索引元组与zipcode条件匹配 但不符合 lastname条件。

默认情况下启用索引条件下推。可以optimizer_switch通过设置index_condition_pushdown标志来控制 系统变量 :

SET optimizer_switch = ‘index_condition_pushdown=off‘;
SET optimizer_switch = ‘index_condition_pushdown=on‘;

总结

1.对于 where constant + like查询可以尝试使用联合索引

// name和stu_id有联合索引
explain select * from course where name = ‘ww‘ and stu_id like ‘%4%‘;

2.对于 where constant + order by index column可以尝试使用联合索引;

// name和stu_id有联合索引
explain select * from course where  name = ‘ww‘ order by stu_id;

以上另种情况都会使用Using index condition。第一种是过滤like的模糊匹配,第二种是进行联合索引的排序。

索引下推经常使用的场景:

  • 对于二级索引
  • select的列不使用覆盖索引
  • 多条件查询(where中多条件,where + order by) + 联合索引
参考

Index Condition Pushdown Optimization

以上是关于mysql索引问题,现在关于where条件有status、cate_id、price三个,ORDER BY分别可能likes、hits、id排序的主要内容,如果未能解决你的问题,请参考以下文章

mysql where条件使用了or会不会扫全表

mysql 分区的字段 与 where 的条件有啥样的关系啊

有些 where 条件会导致索引无效

Mysql系列—— 索引下推优化

sqlwhere后可以有多个条件后再嵌套吗

mysql索引问题?