【MySQL】-11 MySQL索引与索引类型

MySQL索引与索引类型

  • MySQL索引
  • MySQL索引类型包括:
    • (1)普通索引
      • 创建方式:
        • 创建索引
        • 修改表结构
        • 创建表的时候直接指定
    • (2)唯一索引
      • 创建方式:
        • 创建索引
        • 修改表结构
        • 创建表的时候直接指定
    • (4)组合索引
    • (5)建立索引的时机
    • (6)索引的不足之处
    • (7)使用索引的注意事项
        • 索引不会包含有NULL值的列
        • 使用短索引
        • 索引列排序
        • like语句操作
        • 不要在列上进行运算
        • 不使用NOT IN和<>操作
    • (8)查询和索引的优化

MySQL索引

索引是快速搜索的关键。MySQL索引的建立对于MySQL的高效运行是很重要的。下面介绍几种常见的MySQL索引类型。

在数据库表中,对字段建立索引可以大大提高查询速度。假如我们创建了一个 mytable表:

CREATE TABLE mytable(   ID INT NOT NULL,    username VARCHAR(16) NOT NULL  );   
我们随机向里面插入了10000条记录,其中有一条:5555, admin。
在查找username="admin"的记录 SELECT * FROM mytable WHERE username='admin';时,
如果在username上已经建立了索引,MySQL无须任何扫描,即准确可找到该记录。相反,MySQL会扫描所有记录,即要查询10000条记录。

索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索包含多个列。

MySQL索引类型包括:

(1)普通索引

这是最基本的索引,它没有任何限制。普通索引(由关键字KEY或INDEX定义的索引)的唯一任务是加快对数据的访问速度。因此,应该只为那些最经常出现在查询条件(WHERE column = …)或排序条件(ORDER BY column)中的数据列创建索引。只要有可能,就应该选择一个数据最整齐、最紧凑的数据列(如一个整数类型的数据列)来创建索引。

创建方式:

创建索引
CREATE INDEX indexName ON mytable(username(length)); 如果是CHARVARCHAR类型,length可以小于字段实际长度;如果是BLOBTEXT类型,必须指定 length,下同。
修改表结构
ALTER mytable ADD INDEX [indexName] ON (username(length))
创建表的时候直接指定
CREATE TABLE mytable(   ID INT NOT NULL,    username VARCHAR(16) NOT NULL,   INDEX [indexName] (username(length))   ); 

###删除索引的语法:

DROP INDEX [indexName] ON mytable;

(2)唯一索引

它与前面的普通索引类似,不同的就是:普通索引允许被索引的数据列包含重复的值。而唯一索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。

创建方式:

创建索引
CREATE UNIQUE INDEX indexName ON mytable(username(length))
修改表结构
ALTER mytable ADD UNIQUE [indexName] ON (username(length))
创建表的时候直接指定
CREATE TABLE mytable(   ID INT NOT NULL,    username VARCHAR(16) NOT NULL,   UNIQUE [indexName] (username(length))   ); 

(3)主键索引

​ 它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候同时创建主键索引:

CREATE TABLE mytable(   ID INT NOT NULL,    username VARCHAR(16) NOT NULL,   PRIMARY KEY(ID)   ); 

当然也可以用 ALTER 命令。记住:一个表只能有一个主键。

与之类似的,外键索引
如果为某个外键字段定义了一个外键约束条件,MySQL就会定义一个内部索引来帮助自己以最有效率的方式去管理和使用外键约束条件。

(4)组合索引

为了形象地对比单列索引和组合索引,为表添加多个字段:

CREATE TABLE mytable(   ID INT NOT NULL,    username VARCHAR(16) NOT NULL,   city VARCHAR(50) NOT NULL,   age INT NOT NULL  ); 

为了进一步榨取MySQL的效率,就要考虑建立组合索引。就是将 name, city, age建到一个索引里:

ALTER TABLE mytable ADD INDEX name_city_age (name(10),city,age); 

建表时,usernname长度为 16,这里用 10。这是因为一般情况下名字的长度不会超过10,这样会加速索引查询速度,还会减少索引文件的大小,提高INSERT的更新速度。

如果分别在 usernname,city,age上建立单列索引,让该表有3个单列索引,查询时和上述的组合索引效率也会大不一样,远远低于我们的组合索引。虽然此时有了三个索引,但MySQL只能用到其中的那个它认为似乎是最有效率的单列索引。

建立这样的组合索引,其实是相当于分别建立了下面三组组合索引:
usernname,city,age usernname,city usernname 为什么没有 city,age这样的组合索引呢?这是因为MySQL组合索引“最左前缀”的结果。简单的理解就是只从最左面的开始组合。并不是只要包含这三列的查询都会用到该组合索引,

下面的几个SQL就会用到这个组合索引:

SELECT * FROM mytable WHREE username="admin" AND city="郑州" 
SELECT * FROM mytable WHREE username="admin"
而下面几个则不会用到:
SELECT * FROM mytable WHREE age=20 AND city="郑州" 
SELECT * FROM mytable WHREE city="郑州"

(5)建立索引的时机

到这里我们已经学会了建立索引,那么我们需要在什么情况下建立索引呢?一般来说,在WHERE和JOIN中出现的列需要建立索引,但也不完全如此,因为MySQL只对<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE才会使用索引。
例如:

SELECT t.Name  FROM mytable t LEFT JOIN mytable m    ON t.Name=m.username WHERE m.age=20 AND m.city='郑州' 

此时就需要对city和age建立索引,由于mytable表的userame也出现在了JOIN子句中,也有对它建立索引的必要。

刚才提到只有某些时候的LIKE才需建立索引。因为在以通配符%和_开头作查询时,MySQL不会使用索引。like操作一般在全文索引中会用到(InnoDB数据表不支持全文索引)。

例如下句会使用索引:
SELECT * FROM mytable WHERE username like'admin%'
而下句就不会使用:
SELECT * FROM mytable WHEREt Name like'%admin' 因此,在使用LIKE时应注意以上的区别。

(6)索引的不足之处

上面都在说使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:

虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存索引文件。建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会膨胀很快。索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。
因此应该只为最经常查询和最经常排序的数据列建立索引。注意,如果某个数据列包含许多重复的内容,为它建立索引就没有太大的实际效果。从理论上讲,完全可以为数据表里的每个字段分别建一个索引,但MySQL把同一个数据表里的索引总数限制为16个。

(7)使用索引的注意事项

使用索引时,有以下一些技巧和注意事项:

索引不会包含有NULL值的列

只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。

使用短索引

对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的列,如果在前10个或20个字符内,多数值是惟一的,那么就不要对整个列进行索引。

短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。在绝大多数应用里,数据库中的字符串数据大都以各种各样的名字为主,把索引的长度设置为10~15个字符已经足以把搜索范围缩小到很少的几条数据记录了。

索引列排序

MySQL查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。

like语句操作

一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。

不要在列上进行运算

select * from users where YEAR(adddate)<2007; 将在每个行上进行运算,这将导致索引失效而进行全表扫描,因此我们可以改成
select * from users where adddate<‘2007-01-01’;

不使用NOT IN和<>操作

对于not in,可以用not exists或者(外联结+判断为空)来代替;
对于<>,用其它相同功能的操作运算代替,如a<>0 改为 a>0 or a<0

(8)查询和索引的优化

只有当数据库里已经有了足够多的测试数据时,它的性能测试结果才有实际参考价值。如果在测试数据库里只有几百条数据记录,它们往往在执行完第一条查询命令之后就被全部加载到内存里,这将使后续的查询命令都执行得非常快–不管有没有使用索引。

只有当数据库里的记录超过了1000条、数据总量也超过了 MySQL服务器上的内存总量时,数据库的性能测试结果才有意义。

在不确定应该在哪些数据列上创建索引的时候,人们从EXPLAIN SELECT命令那里往往可以获得一些帮助。这其实只是简单地给一条普通的SELECT命令加一个EXPLAIN关键字作为前缀而已。

有了这个关键字,MySQL将不是去执行那条SELECT命令,而是去对它进行分析。MySQL将以表格的形式把查询的执行过程和用到的索引(如果有的话)等信息列出来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/673429.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker安装及介绍

一、Docker的介绍 1.1、什么是Docker Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实…

Unity引擎学习笔记之【动画层操作】

动画层Animation Layer 一、动画器的三个基本状态 1. Any State&#xff08;任意状态&#xff09; “Any State”&#xff08;任意状态&#xff09;&#xff1a;这个状态可以用来连接多个状态机的任意状态转换。在动画控制器中&#xff0c;你可以使用“Any State”作为过渡条…

Python基础语法(内置Python, pycharm配置方式)

一.工具安装与配置 1.Python解释器的安装 官网网址:https://www.python.org/ 选择downloads即可(Windows用户点击Windows, 苹果用户点击macOS) 找到最新版本, 并选择 Download Windows installer (64-bit) 下载完成后可在得到一个安装包进行安装(安装时间较长) 安装完成后…

NLP_“预训练+微调大模型”模式和Prompt/Instruct模式的异同

文章目录 “预训练微调大模型”的模式以提示/指令模式直接使用大模型“预训练微调大模型”模式和Prompt/Instruct模式的异同小结 “预训练微调大模型”的模式 经过预训练的大模型所习得的语义信息和所蕴含的语言知识&#xff0c;很容易向下游任务迁移。NLP应用人员可以根据自己…

Java中处理I/O操作的不同方式:BIO,NIO,AIO

Java中处理I/O操作的不同方式&#xff1a;BIO&#xff0c;NIO&#xff0c;AIO 亲爱的朋友&#xff0c; 在这美好的时刻&#xff0c;愿你感受到生活的温暖和欢乐。愿你的每一天都充满着笑容和满足&#xff0c;无论面对什么挑战都能勇往直前&#xff0c;化解困境。 希望你的心中充…

初识C语言·预处理详解

目录 1 预定义符号 2 define定义常量 3 #define定义宏 4 带有副作用的宏 5 宏替换的规则 6 宏和函数的对比 7 # 和 ## i) #运算符 ii) ##运算符 8 命名约定 9 命令行定义 10 条件编译 条件编译1&#xff1a; 条件编译2&#xff1a; 条件编译3&#xff1a; 条件…

昆仑万维发布天工 2.0 大语言模型及AI助手App;AI成功破解2000年前碳化古卷轴

&#x1f989; AI新闻 &#x1f680; 昆仑万维发布天工 2.0 大语言模型及AI助手App 摘要&#xff1a;昆仑万维近日推出了新版MoE大语言模型“天工 2.0”和相应的“天工 AI 智能助手”App&#xff0c;宣称为国内首个面向C端用户免费的基于MoE架构的千亿级参数大模型应用。天工…

每天一个数据分析题(一百五十六)

在数据建模过程中&#xff0c;对于变量的筛选与维度归约&#xff0c;以下哪项描述是正确的&#xff1f; A. 主成分分析适用于可解释性较强的预测模型&#xff0c;因为它减少了变量间的相关性。 B. 变量聚类旨在通过保留所有变量来减少信息损失&#xff0c;适合于所有类型的数…

【力扣 - 时间复杂度和空间复杂度】

力扣刷题时&#xff0c;题目要求里经常有时间复杂度和空间复杂度的要求。那么&#xff0c;什么是时间复杂度和空间复杂度呢&#xff1f; 定义 时间复杂度和空间复杂度都是用于衡量算法性能的指标&#xff0c;但它们分别从不同的角度来评估算法的效率。 时间复杂度&#xff1a…

UE4 C++创建摄像机摇臂和相机并且设置Transform

新建MyPawn C类 .h #include "GameFramework/SpringArmComponent.h" //SpringArm组件 #include "Camera/CameraComponent.h" //Camera组件class 工程名称_API AMyPawn : public APawn { //定义组件变量 public:UPROPERTY(VisibleAnywhere, BlueprintRead…

Android:IntentActivity,Service,BroadcastReceiver

3.14 Android三大组件 1、Intent页面跳转 Intent(意图):将要做某一件事。Android的3大组件:Activity、Service、BroadcastReceiver,通过Intent启动,并且Intent可以携带数据。 Intent类方法setComponent()设置组件; setClass(packageContext,cls)设置类、 setActi…

CGAL::2D Arrangements-8

8.拓扑Traits 拓扑特征类封装了Arrangement_on_surface_2<GeometryTraits_2&#xff0c;TopologyTraits>类模板和外围模块使用的拓扑实体的定义和处理这些拓扑实体的函数的实现。每个拓扑特征类都必须对基本概念ArrangementBasicTopologyTraits进行建模。这一基本概念的…

C#,字符串相似度的莱文斯坦距离(Levenshtein Distance)算法与源代码

一、莱文斯坦&#xff08;Levenshtein&#xff09; Vladimir I. Levenshtein 弗拉基米尔I列文施坦博士是纠错码理论的先驱&#xff0c;被称为俄罗斯编码理论之父。Levenshtein是莫斯科俄罗斯科学院Keldysh应用数学研究所的研究教授&#xff0c;他的贡献体现在消费者的日常生活中…

PyTorch中torchvision库的详细介绍

torchvision 是 PyTorch 生态系统中的一个关键库&#xff0c;专门为计算机视觉任务设计和优化。它提供了以下几个核心功能&#xff1a; 数据集&#xff1a;内置了多种广泛使用的图像和视频数据集&#xff0c;如 MNIST、CIFAR10/100、Fashion-MNIST、ImageNet、COCO 等&#xff…

Linux中的numactl命令指南

假设我们想控制线程如何被分配到处理器核心&#xff0c;或者选择我们想分配数据的位置&#xff0c;那么numactl命令就适合此类任务。在这篇文章中&#xff0c;我们讨论了如何使用numactl命令执行此类操作。 目录&#xff1a; 介绍语法命令总结参考文献 简介 现代处理器采用…

QGIS编译(跨平台编译)之五十一:Shapelib编译(Windows、Linux、MacOS环境下编译)

文章目录 一、Shapelib介绍二、Shapelib下载三、Windows下编译四、Linux下编译五、MacOS下编译一、Shapelib介绍 Shapelib是一个开源的C/C++库,用于读取、写入和处理ESRI Shapefile格式的空间数据。Shapefile是一种常用的GIS数据格式,包含矢量数据,如点、线、面等。Shapeli…

rkmedia使用记录

1.函数 1&#xff09; RK_MPI_VI_SetChnAttr _CAPI RK_S32 RK_MPI_VI_SetChnAttr(VI_PIPE ViPipe, VI_CHN ViChn,const VI_CHN_ATTR_S *pstChnAttr); /*VI通道属性结构体指针1&#xff09;pcVideoNode&#xff1a;video节点路径2&#xff09;u32BufCnt&#xff1a;VI捕获视频…

ROS学习笔记13:导航相关消息

前言 本人ROS小白&#xff0c;利用寒假时间学习ROS&#xff0c;在此以笔记的方式记录自己每天的学习过程。争取写满20篇(13/20)。 环境&#xff1a;Ubuntu20.04、ROS1&#xff1a;noetic 环境配置&#xff1a;严格按照下方学习链接的教程配置&#xff0c;基本一次成功。 学习链…

VBA技术资料MF116:测试操作系统是否为64位

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。我的教程一共九套&#xff0c;分为初级、中级、高级三大部分。是对VBA的系统讲解&#xff0c;从简单的入门&#xff0c;到…

洛谷P1039 [NOIP2003提高组]侦探推理

题目描述 明明同学最近迷上了侦探漫画《柯南》并沉醉于推理游戏之中&#xff0c;于是他召集了一群同学玩推理游戏。游戏的内容是这样的&#xff0c;明明的同学们先商量好由其中的一个人充当罪犯&#xff08;在明明不知情的情况下&#xff09;&#xff0c;明明的任务就是找出这…