mysql怎么会不走索引,sql查询不走索引
mysqlunionall无法走索引
mysqlunionall无法走索引11 27
我们提供的服务有:网站设计、成都网站制作、微信公众号开发、网站优化、网站认证、寿县ssl等。为近千家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的寿县网站制作公司
1. like %%失效。 方案:改为like %,只写后面的%就能走索引。
2. 虽然有索引,但是查询条件没有索引列或者order by 排序没有索引列。 方案:让查询条件有索引列
3. 索引列存在null值的情况。 方案:索引列如果没有值,则给空字符串或者数字的0,总之就是不要设置null
技术分享 | 为什么 SELECT 查询选择全表扫描,而不走索引?
SQL的执行成本(cost)是 MySQL 优化器选择 SQL 执行计划时一个重要考量因素。当优化器认为使用索引的成本高于全表扫描的时候,优化器将会选择全表扫描,而不是使用索引。
下面通过一个实验来说明。
如下结构的一张表,表中约有104w行数据:
查询1,并未用到ct_index(create_time)索引:
而查询2,则用到了ct_index(create_time)索引:
这里使用optimizer trace工具,观察MySQL对SQL的优化处理过程:
获得关于此SQL的详细优化器处理信息:
通过逐行阅读,发现优化器在join_optimization(SQL优化阶段)部分的rows_estimation内容里:
通过观察优化器的信息,不难发现,使用索引扫描行数约52w行,而全表扫描约为104w行。为什么优化器反而认为使用索引的成本比全表扫描还高呢?
因为当ct_index(create_time)这个普通索引并不包括查询的所有列,因此需要通过ct_index的索引树找到对应的主键id,然后再到id的索引树进行数据查询,即回表(通过索引查出主键,再去查数据行),这样成本必然上升。尤其是当回表的数据量比较大的时候,经常会出现MySQL优化器认为回表查询代价过高而不选择索引的情况。
这里可以回头看查询1 和 查询2的数据量占比:
另外,在MySQL的官方文档中对此也有简要的描述:
参考文档:
="或"'>MySQL使用">="或"
2020-02-27
最近一个日志页面查询很慢,然后去跟踪了查询sql,发现日期字段上即使建了索引,查询还是很慢,执行语句还是使用了全表扫描,于是继续分析下去。
查询语句类似:
select * from logs where createtime = '2020-01-01' ;
起初因为date上没检索,查询执行的是全表扫描,给条件字段createtime建上索引:
再次执行:
查询执行的还是全表扫描:
网上查询有说是因为在查询数据条数约占总条数五分之一以下时能够使用到索引,但超过五分之一时,使用全表扫描。于是把日期范围缩小:
果真,查询执行的是range:
由此可知,在进行范围查询时,比如:、 、=、=等, 如果数据量过大的话,即使where条件字段已经建立了索引,查询语句执行时还是有可能进行全表扫描的。
实际上是不是全表的五分之一以下才会使用索引,这个不能确定,以后再研究了。
索引失效的情况有哪些
原因有如下:
1、最佳左前缀原则——如果索引了多列,要遵守最左前缀原则。指的是查询要从索引的最左前列开始并且不跳过索引中的列。
2、不在索引列上做任何操作,会导致索引失效而导致全表扫描。
3、存储引擎不能使用索引中范围条件右边的列,范围之后索引失效。这写条件判断最后放到后面,先定位到小的范围再开始。
4、mysql使用不等于(!= 或者)的时候,无法使用索引,会导致索引失效。
5、mysql中使用is not null 或者 is null会导致无法使用索引。
6、mysql中like查询是以%开头,索引会失效变成全表扫描,覆盖索引。
7、mysql中,如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)。要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引。
8、如果mysql使用全表扫描要比使用索引快,则不会使用到索引。
注意事项
1、索引列有函数处理或隐式转换,不走索引。
2、索引列倾斜,个别值查询时,走索引代价比走全表扫描高,所以不走索引。
3、索引列没有限制 not null,索引不存储空值,如果不限制索引列是not null,oracle会认为索引列有可能存在空值,所以不会按照索引计算。
当前名称:mysql怎么会不走索引,sql查询不走索引
网站网址:http://pwwzsj.com/article/hchocc.html