首页 > 其他分享 >索引

索引

时间:2023-07-12 17:44:20浏览次数:20  
标签:index 查询 索引 排序 ref 主键

1.索引设计原则

  • 对查询频次较高,且数据量比较大的表建立索引。

  • 索引字段的选择,最佳候选列应当从where子句的条件中提取,如果where子句中的组合比较多,那么应当挑选最常用、过滤效果最好的列的组合。

  • 使用唯一索引,区分度越高,使用索引的效率越高。

2.explain分析执行计划

  id 字段是 select查询的序列号,是一组数字,表示的是查询中执行select子句或者是操作表的顺序。

  (1) id 相同表示加载表的顺序是从上到下。

  (2) id 不同id值越大,优先级越高,越先被执行。

  (3) id 有相同,也有不同,同时存在。id相同的可以认为是一组,从上往下顺序执行;在所有的组中,id的值越大,优先级越高,越先执行。

3.explain 之 select_type

 表示 SELECT 的类型,常见的取值,如下表所示:

select_type含义
SIMPLE 简单的select查询,查询中不包含子查询或者UNION
PRIMARY 查询中若包含任何复杂的子查询,最外层查询标记为该标识
SUBQUERY 在SELECT 或 WHERE 列表中包含了子查询
DERIVED 在FROM 列表中包含的子查询,被标记为 DERIVED(衍生) MYSQL会递归执行这些子查询,把结果放在临时表中
UNION 若第二个SELECT出现在UNION之后,则标记为UNION ; 若UNION包含在FROM子句的子查询中,外层SELECT将被标记为 : DERIVED
UNION RESULT 从UNION表获取结果的SELECT
4.explain 之 table
   展示这一行的数据是关于哪一张表的
5.explain 之 type

  type 显示的是访问类型,是较为重要的一个指标,可取值为:

type含义
NULL MySQL不访问任何表,索引,直接返回结果
system 表只有一行记录(等于系统表),这是const类型的特例,一般不会出现
const 表示通过索引一次就找到了,const 用于比较primary key 或者 unique 索引。因为只匹配一行数据,所以很快。如将主键置于where列表中,MySQL 就能将该查询转换为一个常亮。const于将 "主键" 或 "唯一" 索引的所有部分与常量值进行比较
eq_ref 类似ref,区别在于使用的是唯一索引,使用主键的关联查询,关联查询出的记录只有一条。常见于主键或唯一索引扫描
ref 非唯一性索引扫描,返回匹配某个单独值的所有行。本质上也是一种索引访问,返回所有匹配某个单独值的所有行(多个)
range 只检索给定返回的行,使用一个索引来选择行。 where 之后出现 between , < , > , in 等操作。
index index 与 ALL的区别为 index 类型只是遍历了索引树, 通常比ALL 快, ALL 是遍历数据文件。
all 将遍历全表以找到匹配的行
 

  结果值从最好到最坏依次是:

NULL > system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
system > const > eq_ref > ref > range > index > ALL

  一般来说, 我们需要保证查询至少达到 range 级别, 最好达到ref 。

6.explain 之 rows

  扫描行的数量

7.explain 之 extra

  其他的额外的执行计划信息,在该列展示 

extra含义
using filesort 说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取, 称为 “文件排序”, 效率低。
using temporary 使用了临时表保存中间结果,MySQL在对查询结果排序时使用临时表。常见于 order by 和 group by; 效率低
using index 表示相应的select操作使用了覆盖索引, 避免访问表的数据行, 效率不错。

 

8.避免索引失效

(1). 全值匹配 ,对索引中所有列都指定具体值。

(2). 最左前缀法则    如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始,并且不跳过索引中的列。

(3). 范围查询右边的列,不能使用索引 。

(4). 不要在索引列上进行运算操作, 索引将失效。

(5). 字符串不加单引号,造成索引失效。

(6). 尽量使用覆盖索引,避免select *

   尽量使用覆盖索引(只访问索引的查询(索引列完全包含查询列)),减少select * 。

   如果查询列,超出索引列,也会降低性能。

 (7). 用or分割开的条件, 如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到。

    (8). 以%开头的Like模糊查询,索引失效。

   如果仅仅是尾部模糊匹配,索引不会失效。如果是头部模糊匹配,索引失效。

   通过覆盖索引来解决 

    (9). 如果MySQL评估使用索引比全表更慢,则不使用索引。     (10). is NULL , is NOT NULL 有时索引失效。     (11). in 走索引, not in 索引失效。     (12). 单列索引和复合索引。

9.SQL优化

 1 大批量插入数据

(1) 主键顺序插入

因为InnoDB类型的表是按照主键的顺序保存的,所以将导入的数据按照主键的顺序排列,可以有效的提高导入数据的效率。如果InnoDB表没有主键,那么系统会自动默认创建一个内部列作为主键,所以如果可以给表创建一个主键,将可以利用这点,来提高导入数据的效率。

(2) 关闭唯一性校验

在导入数据前执行 SET UNIQUE_CHECKS=0,关闭唯一性校验,在导入结束后执行SET UNIQUE_CHECKS=1,恢复唯一性校验,可以提高导入的效率。

(3) 手动提交事务

如果应用使用自动提交的方式,建议在导入前执行 SET AUTOCOMMIT=0,关闭自动提交,导入结束后再执行 SET AUTOCOMMIT=1,打开自动提交,也可以提高导入的效率。

2 优化order by语句

1). 第一种是通过对返回数据进行排序,也就是通常说的 filesort 排序,所有不是通过索引直接返回排序结果的排序都叫 FileSort 排序。

 2). 第二种通过有序索引顺序扫描直接返回有序数据,这种情况即为 using index,不需要额外排序,操作效率高。 了解了MySQL的排序方式,优化目标就清晰了:尽量减少额外的排序,通过索引直接返回有序数据。where 条件和Order by 使用相同的索引,并且Order By 的顺序和索引顺序相同, 并且Order by 的字段都是升序,或者都是降序。否则肯定需要额外的操作,这样就会出现FileSort。
5.3.3 Filesort 的优化

通过创建合适的索引,能够减少 Filesort 的出现,但是在某些情况下,条件限制不能让Filesort消失,那就需要加快 Filesort的排序操作。对于Filesort , MySQL 有两种排序算法:

1) 两次扫描算法 :MySQL4.1 之前,使用该方式排序。首先根据条件取出排序字段和行指针信息,然后在排序区 sort buffer 中排序,如果sort buffer不够,则在临时表 temporary table 中存储排序结果。完成排序之后,再根据行指针回表读取记录,该操作可能会导致大量随机I/O操作。

2)一次扫描算法:一次性取出满足条件的所有字段,然后在排序区 sort buffer 中排序后直接输出结果集。排序时内存开销较大,但是排序效率比两次扫描算法要高。

 

MySQL 通过比较系统变量 max_length_for_sort_data 的大小和Query语句取出的字段总大小, 来判定是否那种排序算法,如果max_length_for_sort_data 更大,那么使用第二种优化之后的算法;否则使用第一种。

可以适当提高 sort_buffer_size 和 max_length_for_sort_data 系统变量,来增大排序区的大小,提高排序的效率。

5.4 优化group by 语句

由于GROUP BY 实际上也同样会进行排序操作,而且与ORDER BY 相比,GROUP BY 主要只是多了排序之后的分组操作。当然,如果在分组的时候还使用了其他的一些聚合函数,那么还需要一些聚合函数的计算。所以,在GROUP BY 的实现过程中,与 ORDER BY 一样也可以利用到索引。

如果查询包含 group by 但是用户想要避免排序结果的消耗, 则可以执行order by null 禁止排序。

创建索引 :

5.5 优化嵌套查询

Mysql4.1版本之后,开始支持SQL的子查询。这个技术可以使用SELECT语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中。使用子查询可以一次性的完成很多逻辑上需要多个步骤才能完成的SQL操作,同时也可以避免事务或者表锁死,并且写起来也很容易。但是,有些情况下,子查询是可以被更高效的连接(JOIN)替代。

连接(Join)查询之所以更有效率一些 ,是因为MySQL不需要在内存中创建临时表来完成这个逻辑上需要两个步骤的查询工作。

5.6 优化OR条件

对于包含OR的查询子句,如果要利用索引,则OR之间的每个条件列都必须用到索引 , 而且不能使用到复合索引; 如果没有索引,则应该考虑增加索引。

建议使用 union 替换 or :

我们来比较下重要指标,发现主要差别是 type 和 ref 这两项

type 显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是:

system > const > eq_ref > ref > fulltext > ref_or_null  > index_merge > unique_subquery > index_subquery > range > index > ALL

UNION 语句的 type 值为 ref,OR 语句的 type 值为 range,可以看到这是一个很明显的差距

UNION 语句的 ref 值为 const,OR 语句的 type 值为 null,const 表示是常量值引用,非常快

这两项的差距就说明了 UNION 要优于 OR 。

5.7 优化分页查询

一般分页查询时,通过创建覆盖索引能够比较好地提高性能。一个常见又非常头疼的问题就是 limit 2000000,10 ,此时需要MySQL排序前2000010 记录,仅仅返回2000000 - 2000010 的记录,其他记录丢弃,查询排序的代价非常大 。

5.7.1 优化思路一

在索引上完成排序分页操作,最后根据主键关联回原表查询所需要的其他列内容。

5.7.2 优化思路二

该方案适用于主键自增的表,可以把Limit 查询转换成某个位置的查询 。

标签:index,查询,索引,排序,ref,主键
From: https://www.cnblogs.com/record-100/p/17548359.html

相关文章

  • 一个突破搜索引擎的信息茧房方法
    搜索引擎为我们提供了一个广阔的知识世界,通过基于关键词的搜索算法,帮助我们快速、准确地找到所需的信息,包括文章、新闻、图片、视频等各种类型的内容。所以我们要善于使用搜索引擎,帮助我们探索知识、寻找答案和解决问题,扩展自己的知识储备和理解世界。突破搜索引擎的信息茧房在......
  • logstash+Elasticseach单节点 让logstash生成单副本索引
    要让Logstash和Elasticsearch生成单副本索引,请按照以下步骤更改Logstash的输出配置文件:打开Logstash配置文件,该文件默认位于 logstash/config 目录下。找到输出部分配置,并添加以下行:output{elasticsearch{hosts=>["localhost"]index=>"your......
  • mysql中innodb的索引结构以及使用B+树实现索引的原因?
    在MySQL中,InnoDB引擎使用B+树数据结构来实现索引。B+树是一种平衡的多叉树,它具有以下优点:有序性:B+树的叶子节点是按照键值大小顺序存储的,这样可以方便地进行范围查询操作,提高查询效率。平衡性:B+树通过自动调整节点的分裂和合并来保持树的平衡,使得所有叶子节点到根节点的路径长度相......
  • 2.mysql的索引
    一、索引概述索引是表的目录,在查找内容之前可以先在目录中查找索引位置,以此快速定位查询数据。对于索引,会保存在额外的文件中。索引是帮助MySQL高效获取数据的排好序的数据结构。平时代码中为了方便查询,我们使用的哈希表、链表、二叉树等数据结构存储相关数据,使用二分、二叉搜......
  • MySQL---索引优化与查询优化
     索引失效案例全值匹配我最爱当where条件的所有字段都有索引完全匹配时,效率最高最左前缀规则(联合索引)联合索引,在检索数据时从联合索引的最左侧开始匹配主键插入顺序计算/函数/类型转换(自动或手动)导致索引失效......
  • 程序员必备:使用AI工具通义千问,没有广告没有假链接,比搜索引擎要便捷多了,回答还算满意
    我提的问题是:使用Python连接Oracle,cx_Oracle和oracledb那个效率更高,功能更全,请列出他们的区别和实例代码回复是:以下是使用Python连接Oracle时,cx_Oracle和oracledb的效率和功能比较及实例代码:效率比较:cx_Oracle是一个Python官方标准库,使用了JIT编译技术,可以提高查询性能。ora......
  • 索引
    字符串数据结构图论最短路动态规划数学计算几何思想与技巧......
  • mysql索引优化(一)
    (1)数据准备建表插入部分数据CREATETABLE`employees`(`id`int(11)NOTNULLAUTO_INCREMENT,`name`varchar(24)NOTNULLDEFAULT''COMMENT'姓名',`age`int(11)NOTNULLDEFAULT'0'COMMENT'年龄',`position`varchar(......
  • 二分法查找目标元素在数组中的索引
    /***给定一个n个元素有序的(升序)整型数组nums和一个目标值target,写一个函数搜索nums中的target,*如果目标值存在返回下标,否则返回-1。*输入:nums=[-1,0,3,5,9,12],target=9*输出:4*解释:9出现在nums中并且下标为4......
  • 新增文章创建索引
                        文章微服务异步调用生成静态文件,上传到minIO之后发送消息到MQ,因为创建索引需要staticurl。packagecom.heima.article.service.impl;importcom.alibaba.fastjson.JSON;importcom.alibaba.fastjson.JSONA......