最左匹配原则中,有如下说明:

  1. 最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
  2. =和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式

表结构如下

mysql 几十万 用模糊查询可以吗 mysql模糊查询效率_字段

SQL语句:

EXPLAIN SELECT
t1.id,
t1.type_id typeId,
t1.brand_id brandId,
t1.model,
t5.configValue comeByName
FROM
t_machine_model_new t1
LEFT JOIN system_config t5 ON t1.source = t5.configKey AND t5.configType = 'data_channel';

没有优化的执行如下:

mysql 几十万 用模糊查询可以吗 mysql模糊查询效率_mysql 几十万 用模糊查询可以吗_02

建立configKey索引执行效率如下:

mysql 几十万 用模糊查询可以吗 mysql模糊查询效率_mysql 几十万 用模糊查询可以吗_03

结论:使用了索引,但是效率不高

尝试建立组合索引如下:

mysql 几十万 用模糊查询可以吗 mysql模糊查询效率_mysql 几十万 用模糊查询可以吗_04

结论:使用了组合索引,但是效率不高,没有变化

mysql索引类型为BTREE类型,树形结构启发,是不是先把内循环次数降下来,configKey→configType的组合次数,要比configType→configKey要多的多

mysql 几十万 用模糊查询可以吗 mysql模糊查询效率_mysql 模糊查询无法使用索引_05

结论:改变组合索引的顺序,先configType,再configKey,受到启发,在建立组合索引的时候,先把索引的排序次数降下来,小(configType)在前大(configKey)在(指的不同值的个数),后得到满意优化结果。

什么是双路排序和单路排序?
双路排序:Mysql4.1之前是使用双路排序,字面的意思就是两次扫描磁盘,最终得到数据,读取行指针和ORDER BY列,对他们进行排序,然后扫描已经排好序的列表,按照列表中的值重新从列表中读取对数据输出。也就是从磁盘读取排序字段,在buffer进行排序,再从磁盘读取其他字段。文件的磁盘IO非常耗时的,所以在Mysql4.1之后,出现了第二种算法,就是单路排序。
单路排序:从磁盘读取查询所需要的所有列,按照ORDER BY在buffer对它进行排序,然后扫描排序后的列表进行输出,它的效率更快一些,避免了第二次读取数据。并且把随机IO变成了顺序IO,但是它会使用更多的空间,因为它把每一行都保存在了内存里。

CREATE INDEX index_t_machine_model_new_srt on t_machine_model_new(create_time desc,srt asc);
上述创建组合索引是能执行的,但是对于desc和asc是失效的,不能一个降序一个升序。
order by create_time,srt 这种查询,比如建立组合索引是这两个字段,要不都升序,要不都降序,不能一个升序一个降序,使组合索引失效。

【字段属性为null】1.  where 条件中有is null 时  索引起作用 数据量大约为4w2.  where 条件中有 is not null 时候 索引起作用(数据量差异性不会很大) 数据:667 走索引

【字段属性为not null】 1.  where 条件中有 is not null 时  索引不起作用2.  where 条件中有 is null 时  索引不起作用

上述可以理解为,既然是查询为空或者不为空,那么你的字段必须要支持为空值,反过来说,字段不支持空值,is not null 和is null的判断是完全没有意义,因为你的数据没有空值数据。

如图下所示例子:

mysql 几十万 用模糊查询可以吗 mysql模糊查询效率_mysql 模糊查询无法使用索引_06

建议优化:要尽可能地把字段定义为 NOT NULL,即使应用程序无须保存 NULL(没有值),也有许多表包含了可空列(Nullable Column)这仅仅是因为它为默认选项。除非真的要保存 NULL,否则就把列定义为 NOT NULLMySQL难以优化引用了可空列的查询,它会使索引、索引统计和值更加复杂。可空列需要更多的储存空间,还需要在MySQL内部进行特殊处理。当可空列被索引的时候,每条记录都需要一个额外的字节,还可能导致 MyISAM 中固定大小的索引(例如一个整数列上的索引)变成可变大小的索引。 即使要在表中储存「没有值」的字段,还是有可能不使用 NULL 的,考虑使用 0、特殊值或空字符串来代替它。 把 NULL 列改为 NOT NULL 带来的性能提升很小,所以除非确定它引入了问题,否则就不要把它当作优先的优化措施。然后,如果计划对列进行索引,就要尽量避免把它设置为可空,虽然在mysql里 Null值的列也是走索引的,是有限制,上述介绍数据量大概4w的数据可行。

最左匹配原则中,有如下说明:

 最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。

 =和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式

表结构如下

mysql 几十万 用模糊查询可以吗 mysql模糊查询效率_mysql 几十万 用模糊查询可以吗_07

SQL语句:

EXPLAIN SELECT
t1.id,
t1.type_id typeId,
t1.brand_id brandId,
t1.model,
t5.configValue comeByName
FROM
t_machine_model_new t1
LEFT JOIN system_config t5 ON t1.source = t5.configKey AND t5.configType = 'data_channel';

没有优化的执行如下:

mysql 几十万 用模糊查询可以吗 mysql模糊查询效率_数据_08

建立configKey索引执行效率如下:

mysql 几十万 用模糊查询可以吗 mysql模糊查询效率_升序_09

结论:使用了索引,但是效率不高

尝试建立组合索引如下:

mysql 几十万 用模糊查询可以吗 mysql模糊查询效率_升序_10

结论:使用了组合索引,但是效率不高,没有变化

mysql索引类型为BTREE类型,树形结构启发,是不是先把内循环次数降下来,configKey→configType的组合次数,要比configType→configKey要多的多

mysql 几十万 用模糊查询可以吗 mysql模糊查询效率_mysql 几十万 用模糊查询可以吗_11

结论:改变组合索引的顺序,先configType,再configKey,受到启发,在建立组合索引的时候,先把索引的排序次数降下来,小(configType)在前大(configKey)在(指的不同值的个数),后得到满意优化结果。

什么是双路排序和单路排序?

双路排序:Mysql4.1之前是使用双路排序,字面的意思就是两次扫描磁盘,最终得到数据,读取行指针和ORDER BY列,对他们进行排序,然后扫描已经排好序的列表,按照列表中的值重新从列表中读取对数据输出。也就是从磁盘读取排序字段,在buffer进行排序,再从磁盘读取其他字段。文件的磁盘IO非常耗时的,所以在Mysql4.1之后,出现了第二种算法,就是单路排序。

单路排序:从磁盘读取查询所需要的所有列,按照ORDER BY在buffer对它进行排序,然后扫描排序后的列表进行输出,它的效率更快一些,避免了第二次读取数据。并且把随机IO变成了顺序IO,但是它会使用更多的空间,因为它把每一行都保存在了内存里。

CREATE INDEX index_t_machine_model_new_srt on t_machine_model_new(create_time desc,srt asc);

上述创建组合索引是能执行的,但是对于desc和asc是失效的,不能一个降序一个升序。

order by create_time,srt 这种查询,比如建立组合索引是这两个字段,要不都升序,要不都降序,不能一个升序一个降序,使组合索引失效。

【字段属性为null】

1.  where 条件中有is null 时  索引起作用    数据量大约为4w

2.  where 条件中有 is not null 时候 索引起作用(数据量差异性不会很大)    数据:667 走索引

【字段属性为not null】 

1.  where 条件中有 is not null 时  索引不起作用

2.  where 条件中有 is null 时  索引不起作用

上述可以理解为,既然是查询为空或者不为空,那么你的字段必须要支持为空值,反过来说,字段不支持空值,is not null 和is null的判断是完全没有意义,因为你的数据没有空值数据。

如图下所示例子:

mysql 几十万 用模糊查询可以吗 mysql模糊查询效率_mysql 模糊查询无法使用索引_12

建议优化:

要尽可能地把字段定义为 NOT NULL,即使应用程序无须保存 NULL(没有值),也有许多表包含了可空列(Nullable Column)

这仅仅是因为它为默认选项。除非真的要保存 NULL,否则就把列定义为 NOT NULL

MySQL难以优化引用了可空列的查询,它会使索引、索引统计和值更加复杂。

可空列需要更多的储存空间,还需要在MySQL内部进行特殊处理。当可空列被索引的时候,

每条记录都需要一个额外的字节,还可能导致 MyISAM 中固定大小的索引(例如一个整数列上的索引)变成可变大小的索引。 

即使要在表中储存「没有值」的字段,还是有可能不使用 NULL 的,考虑使用 0、特殊值或空字符串来代替它。 

把 NULL 列改为 NOT NULL 带来的性能提升很小,所以除非确定它引入了问题,否则就不要把它当作优先的优化措施。

然后,如果计划对列进行索引,就要尽量避免把它设置为可空,虽然在mysql里 Null值的列也是走索引的,是有限制,上述介绍数据量大概4w的数据可行。