26丨索引的使用原则:如何通过索引让SQL查询效率最大化?
26丨索引的使用原则:如何通过索引让SQL查询效率最大化?
讲述:陈旸
时长12:20大小11.30M
创建索引有哪些规律?
什么时候不需要创建索引
什么情况下索引失效
总结
赞 15
提建议
精选留言(60)
- wusiration2019-08-09索引失效,因为使用了date函数。改成SELECT comment_id, comment_text, comment_time FROM product_comment WHERE comment_time BETWEEN DATE('2018-10-01 10:00:00') AND DATE('2018-10-02 10:00:00')
作者回复: Good Job
共 9 条评论49 - Yuhui2019-09-19老师您好!请教一下如何查找“不经常使用的“索引呢?谢谢!
作者回复: 你可以查看下MySQL中的performance_schema.table_io_waits_summary_by_index_usage数据表,它表明了每个索引进行统计的I/O等待事件,其中COUNT_STAR代表了事件的次数。过滤掉一些系统表,查看下数据表中有哪些索引不经常使用,具体的SQL语句:SELECT OBJECT_SCHEMA, OBJECT_NAME, INDEX_NAME,COUNT_STAR FROM performance_schema.table_io_waits_summary_by_index_usage WHERE INDEX_NAME IS NOT NULL AND COUNT_STAR = 0 AND OBJECT_SCHEMA != 'mysql' AND OBJECT_SCHEMA != 'performance_schema'
30 - 黑山老妖2019-08-10老师 SELECT user_id, count(*) as num FROM product_comment group by user_id order by comment_time desc limit 100 这个例子中 对(comment_time,user_id)进行索引 ,老师不是说按照最左原则,索引会失效嘛 为什么还是会起作用,望老师解答 :)共 9 条评论11
- 佚花2019-08-21关于like. %在左边,即使有索引,也会失效. 只有当%在右边时,才会生效
作者回复: 对的 如果%在左侧就是前模糊匹配,有索引也会失效。所以字符串进行匹配的时候,需要最左侧是个明确的字符才能使用上索引。
8 - haer2019-08-09索引失效,因为使用了date函数
作者回复: 对的
7 - 梦想天空2019-08-10老师 您好。使用selet * from T where a<4 or a=9; a有索引,但还是全盘扫描,不知道什么原因共 5 条评论6
- Vackine2019-08-09关于关系型数据库模型介绍的论文,老师有推荐的么✨
作者回复: 一本经典的书《Towards a Logical Reconstruction of Relational Database Theory》 另外关系型数据库里面也有不同的使用场景,比如关于图像检索的 《Chabot: Retrieval from a Relational Database of Images》 查询XML的: 《Storing and querying ordered XML using a relational database system》
5 - Andywu2019-08-26去掉date函数后,查看执行计划,索引生效了。 mysql> explain SELECT comment_id, comment_text, comment_time FROM product_comment WHERE comment_time >= '2018-10-01 10:00:00' AND comment_time <= '2018-10-02 10:00:00'; +----+-------------+-----------------+------------+-------+---------------+--------------+---------+------+------+----------+-----------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------------+------------+-------+---------------+--------------+---------+------+------+----------+-----------------------+ | 1 | SIMPLE | product_comment | NULL | range | comment_time | comment_time | 6 | NULL | 2929 | 100.00 | Using index condition | +----+-------------+-----------------+------------+-------+---------------+--------------+---------+------+------+----------+-----------------------+ 1 row in set, 1 warning (0.00 sec) 查询时间缩短为0.01s。 mysql> SELECT comment_id, comment_text, comment_time FROM product_comment WHERE comment_time >= '2018-10-01 10:00:00' AND comment_time <= '2018-10-02 10:00:00'; 2929 rows in set (0.01 sec)展开4
- Goal2019-08-13老师,今天文章中的“product_comment”表结构和数据,是从哪里导入的呢? 个人感觉,本课程用到的所有表都可以放到一个统一的地方,比如之前的 GitHub上面,方便我们统一下载。
作者回复: 因为文件大于100M,就先放到百度网盘:https://pan.baidu.com/s/1LBEAm50DDP9AjErLtGplLg 提取码:32ep 多谢建议,我把它也放到GitHub上,大于100M的给出百度网盘的链接
4 - ABC2019-08-09索引会失效,因为使用了date函数。 如果修改的话,可以用between和and,对查询条件进行转换。 例如:currtime between date('2018-01-10 10:00:00) and date('2018-02-10 12:00:00') 手机回复,没有实际运行,如有错误请老师指正,谢谢展开
作者回复: Good Job
4 - rike2019-12-27“按照 user_id 进行评论分组,同时按照评论时间降序的方式进行排序”,执行对应的sql后,报错。望大神验证一下,不要误导付费学习的读者。
作者回复: 应该是可以运行的,rike同学再试试
共 3 条评论3 - 抢小孩子糖吃2019-11-23老师 如果我们给女儿国的性别加上了索引 我们查看男性的话会快很多 但如果我们有时需要查看男性 有时需要查看女性 还适合在性别上建索引吗 查看女性的时候优化器会选择用这个索引找数据吗
作者回复: 这个看需求,对于某个疾病(发病率很低)的正样本,可以选择创建索引。如果性别男女都需要查看,可以不建索引,对于女性,优化器也不会使用索引进行查找。
3 - niemo2019-08-09老师 您好,sql条件执行顺序不是从右到左么?所有在使用联合索引的时候,把最左的索引写在where条件的最右边,这样理解对么?
作者回复: SQL执行顺序: SELECT DISTINCT player_id, player_name, count(*) as num #顺序5 FROM player JOIN team ON player.team_id = team.team_id #顺序1 WHERE height > 1.80 #顺序2 GROUP BY player.team_id #顺序3 HAVING num > 2 #顺序4 ORDER BY num DESC #顺序6 LIMIT 2 #顺序7
3 - 博弈2020-03-25需要创建索引的情况: 1、 字段值唯一 2、 Where条件 3、 Group by 和order by 4、 Update、delete的where条件 5、 Distinct字段 6、 多表join操作时,表尽量不超过3个,对where条件创建索引,对连接的字段创建索引且类型一致 7、 多个单列索引在多条件查询时只会生效一个索引(MySQL 会选择其中一个限制最严格的作为索引),所以在多条件联合查询的时候最好创建联合索引。 不需要创建索引的情况: 1、 WHERE 条件(包括 GROUP BY、ORDER BY)里用不到的字段不需要创建索引 2、 如果表记录太少,比如少于 1000 个,那么是不需要创建索引的 3、 字段中如果有大量重复数据,也不用创建索引,比如性别字段 4、 频繁更新的字段不一定要创建索引 索引失效的情况: 1、 如果索引进行了表达式计算,则会失效 2、 如果对索引使用函数,也会造成失效 3、 在 WHERE 子句中,如果在 OR 前的条件列进行了索引,而在 OR 后的条件列没有进行索引,那么索引会失效 4、 当我们使用 LIKE 进行模糊查询的时候,后面不能是 % 5、 索引列尽量设置为 NOT NULL 约束 6、 我们在使用联合索引的时候要注意最左原则展开2
- 加载中……2019-08-30老师好,请教个问题,有没有经验数据,在索引区分度低于“某个值”(80%)的时候,就不适合在这个列上建立索引了?
作者回复: 重复值高的字段一般不创建索引,重复率高于10%可以考虑不创建索引,具体情况也要具体分析,比如通常我们都不应该给性别字段创建索引,因为重复度高,但是如果数据集是女人国,男性比例只有0.01%,而且我们想要查询哪些为男性的情况,此时我们使用索引进行查询效率会更高。这种情况也适用于某种疾病的查询,是否患有某个罕见病的数值为0或者1,且疾病的发病率(数值=1的情况)往往很低,但是如果我们想要进行查询哪些人患病了这种疾病,将这个字段创建索引进行查询效率高,因为我们想要查找的这个人群区分度还是很高的。
2 - Geek_Wison2019-08-09老师您好,本节的内容我有个疑惑的地方:创建联合索引(comment_time, user_id),但是查询语句是先GROUP BY,然后再ORDER BY,那这样子的话,这个联合索引不是应该不符合最左侧原则而失效了吗?
作者回复: 如果联合索引的中的字段语句都用了,就不会失效,下面有同学回答了,解释的正确。
共 2 条评论2 - Ronnyz2019-08-09作业: 对comment_time使用了函数,索引失效 SELECT comment_id, comment_text, comment_time FROM product_comment WHERE comment_time BETWEEN DATE('2018-10-01 10:00:00') AND DATE('2018-10-02 10:00:00'); 2888 rows in set (1.60 sec)展开
作者回复: 正确
2 - 卡布2019-12-04KLOOK校招面试的时候就问了索引,那时候对索引一概不通,这回得在专栏补回来。
作者回复: 加油卡布
1 - melon2019-08-13老师 为什么group by 后的列要加索引呢?
作者回复: 提升检索效率
1 - LiuChen2019-08-09老师,对于已有的表结构去创建索引,创建后就直接可以用吗?需不需要其他操作?
作者回复: 直接用就可以,就是看能否使用上索引,你可以用 EXPLAIN来检查下,看看SQL语句是否用到了索引
1