mysql|使用索引后的效果

没使用索引

mysql> EXPLAIN select * from employees where first_name="Sahrah";
+----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| id | select_type | table     | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra       |
+----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+-------------+
|  1 | SIMPLE      | employees | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 299290 |    10.00 | Using where |
+----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+-------------+
1 row in set, 1 warning (0.01 sec)

使用索引

mysql> create index index_test on employees(first_name);
mysql> EXPLAIN select * from employees where first_name="Sahrah";
+----+-------------+-----------+------------+------+---------------+------------+---------+-------+------+----------+-------+
| id | select_type | table     | partitions | type | possible_keys | key        | key_len | ref   | rows | filtered | Extra |
+----+-------------+-----------+------------+------+---------------+------------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | employees | NULL       | ref  | index_test    | index_test | 58      | const |  217 |   100.00 | NULL  |
+----+-------------+-----------+------------+------+---------------+------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

很直观的可以看出没使用索引前扫描约299290行数据,使用了之后只扫描217条数据,filtered表示扫描结果有百分之几符合where条件

小贴士:

索引不能生效的场景:

1.当字段成为函数参数时候

    SELECT * FROM employees WHERE UPPER(first_name) = 'SAHRAH';

    2.当模糊匹配为%开头时

    SELECT * FROM employees WHERE first_name LIKE '%ah';

    3.复合索引的左前缀原则,当创建复合索引(first_name, last_name),但是使用语句如下所示时不会触发索引优势

    SELECT * FROM employees WHERE last_name = 'Smith';

    正确的应该是

    SELECT * FROM employees WHERE first_name = 'Sahrah';

    或者

    SELECT * FROM employees WHERE first_name="Sahrah" AND last_name = 'Smith';

    4.低选择性或者返回数据量过大

    SELECT * FROM employees WHERE gender = 'M';

    假设 gender 列只有两个值(如 'M' 和 'F'),而且 'M' 的数据占比很高,在这种情况下,即使 gender 上有索引,优化器可能会认为全表扫描更高效,因为索引过滤的效果不明显

    5.OR条件中部分无索引,假设 first_name 有索引,而 last_name 没有,MySQL 使用OR条件的时候无法通过索引合并高效地执行查询,而最终选择全表扫描

    SELECT * FROM employees WHERE first_name="Sahrah" OR last_name = 'Smith';

    6.数据类型不匹配

    SELECT * FROM employees WHERE CAST(employee_id AS CHAR) = '123';

    即使 employee_id 是一个有索引的整数列,通过 CAST() 将其转换为字符类型后,原有的索引顺序就失去了作用,优化器因此不能利用该索引

    7.表达式运算

    SELECT * FROM employees WHERE salary + bonus > 5000;

    即使 salary 或 bonus 分别有索引,这个由运算生成的值不能直接对应到索引结构,因此索引不会被用于该条件的过滤

    暂无评论

    发送评论 编辑评论

    
    				
    |´・ω・)ノ
    ヾ(≧∇≦*)ゝ
    (☆ω☆)
    (╯‵□′)╯︵┴─┴
     ̄﹃ ̄
    (/ω\)
    ∠( ᐛ 」∠)_
    (๑•̀ㅁ•́ฅ)
    →_→
    ୧(๑•̀⌄•́๑)૭
    ٩(ˊᗜˋ*)و
    (ノ°ο°)ノ
    (´இ皿இ`)
    ⌇●﹏●⌇
    (ฅ´ω`ฅ)
    (╯°A°)╯︵○○○
    φ( ̄∇ ̄o)
    ヾ(´・ ・`。)ノ"
    ( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
    (ó﹏ò。)
    Σ(っ °Д °;)っ
    ( ,,´・ω・)ノ"(´っω・`。)
    ╮(╯▽╰)╭
    o(*////▽////*)q
    >﹏<
    ( ๑´•ω•) "(ㆆᴗㆆ)
    😂
    😀
    😅
    😊
    🙂
    🙃
    😌
    😍
    😘
    😜
    😝
    😏
    😒
    🙄
    😳
    😡
    😔
    😫
    😱
    😭
    💩
    👻
    🙌
    🖕
    👍
    👫
    👬
    👭
    🌚
    🌝
    🙈
    💊
    😶
    🙏
    🍦
    🍉
    😣
    Source: github.com/k4yt3x/flowerhd
    颜文字
    Emoji
    小恐龙
    花!