首页 > 试题广场 >

请你说说MySQL索引,以及它们的好处和坏处

[问答题]
请你说说MySQL索引,以及它们的好处和坏处
MySQL索引是一种帮助快速查找数据的数据结构,可以把它理解为书的目录,通过索引能够快速找到数据所在位置。场景的索引数据结构有:Hash表(通过hash算法快速定位数据,但不适合范围查询,因为需要每个key都进行一次hash)、二叉树(查找和修改效率都比较高),但是在InnoDB引擎中使用的索引是B+Tree,相较于二叉树,B+Tree这种多叉树,更加矮宽,更适合存储在磁盘中。使用索引增加了数据查找的效率,但是相对的由于索引也需要存储到磁盘,所以增加了存储的压力,并且新增数据时需要同步维护索引。但是合理的使用索引能够极大提高我们的效率!
发表于 2022-04-15 10:25:07 回复(31)
优点: 1.大大加快数据的检索速度 2.通过使用索引,可以在查询的过程中使用优化隐藏器,提高系统的性能 缺点: 1.时间方面:创建索引和维护索引要耗费时间,索引需要动态的维护 2.空间方面:需要占物理空间
发表于 2022-04-26 15:13:11 回复(0)
既然是线程安全问题,那么肯定是在多个线程访问的情况下产生的,没有按照我们预期的行为执行,那么线程就不安全了。也就是说我们想要确保在多线程访问的时候,我们的程序还能按照我们预期的行为去执行,那么就是线程安全。确保线程安全,不可变(final):在java语言中,不可变的对象一定是线程安全的,无论是对象的方法实现还是方法的调用者,都不需要再采取任何的线程安全保障措施。final关键字修饰的类或数据不可修改,可靠性最高。如 String类,Integer类。线程封闭:把对象封装到一个线程里,只有一个线程能看到这个对象,那么这个对象就算不是线程安全的,也不会出现任何线程安全方面的问题。线程封闭有三种:Ad-hoc 线程封闭,Ad-hoc线程封闭是指维护线程封闭性的职责完全由程序实现来承担。Ad-hoc线程封闭是非常脆弱的,因为没有任何一种语言特性,例如可见性修饰符或局部变量,能将对象封闭到目标线程上。事实上,对线程封闭对象(例如,GUI应用程序中的可视化组件或数据模型等)的引用通常保存在公有变量中。ThreadLocal线程封闭,它是一个特别好的封闭方法,其实ThreadLocal内部维护了一个map,map的key是每个线程的名称,而map的value就是我们要封闭的对象。ThreadLocal提供了get、set、remove方法,每个操作都是基于当前线程的,所以它是线程安全的。堆栈封闭 堆栈封闭其实就是方法中定义局部变量。不存在并发问题。多个线程访问一个方法的时候,方法中的局部变量都会被拷贝一份到线程的栈中(Java内存模型),所以局部变量是不会被多个线程所共享的。同步:悲观锁,非阻塞同步(乐观锁),锁优化(过度优化),悲观锁 同步的最常用的方法是使用锁(Lock),它是一种非强制机制,每个线程在访问数据或资源之前首先试图获取锁,并在访问结束之后释放锁;在锁已经被占用的时候试图获取锁时,线程会等待,直到锁重新可用。 synchronized关键字,就是用来控制线程同步的,保证我们的线程在多线程环境下,不被多个线程同时执行,确保我们数据的完整性,。可重入,修饰(class、obj、代码块)。 可重入:一个函数被重入,表示这个函数没有执行完成,但由于外部因素或内部因素,又一次进入该函数执行。一个函数称为可重入的,表明该函数被重入之后不会产生任何不良后果。可重入是并发安全的强力保障,一个可重入的函数可以在多线程环境下放心使用。 注意:虽然加synchronized关键字,可以让我们的线程变得安全,但是我们在用的时候,也要注意缩小synchronized的使用范围,如果随意使用时很影响程序的性能,别的对象想拿到锁,结果你没用锁还一直把锁占用,这样就有点浪费资源。 Lock.lock()/Lock.unLock(): ReentrantReadWriteLock是Lock的另一种实现方式,我们已经知道了ReentrantLock是一个排他锁,同一时间只允许一个线程访问,而ReentrantReadWriteLock允许多个读线程同时访问,但不允许写线程和读线程、写线程和写线程同时访问。相对于排他锁,提高了并发性。 ReentrantLock也是通过互斥来实现同步。在基本用法上,ReentrantLock与synchronized很相似,他们都具备一样的线程重入特性。 可见性: 可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。 非阻塞同步(乐观锁): 随着硬件指令集的发展,出现了基于冲突检测的乐观并发策略,通俗地说,就是先进行操作,如果没有其他线程争用共享数据,那操作就成功了;如果共享数据有争用,产生了冲突,那就再采用其他的补偿措施。(最常见的补偿错误就是不断地重试,直到成功为止),这种乐观的并发策略的许多实现都不需要把线程挂起,因此这种同步操作称为非阻塞同步。 非阻塞的实现CAS(Compare-and-Swap): CAS指令需要有3个操作数,分别是内存地址(在java中理解为变量的内存地址,用V表示)、旧的预期值(用A表示)和新值(用B表示)。CAS指令执行时,CAS指令指令时,当且仅当V处的值符合旧预期值A时,处理器用B更新V处的值,否则它就不执行更新,但是无论是否更新了V处的值,都会返回V的旧值,上述的处理过程是一个原子操作。 CAS的ABA问题: 因为CAS需要在操作值的时候检查下值有没有发生变化,如果没有发生变化则更新,但是一个值原来是A,变成了B,又变成了A,那么使用CAS进行检查时会发现它的值没有发生变化,但是实际上却变化了。CAS只关注了比较前后的值是否改变,而无法清楚在此过程中变量的变更明细,这就是所谓的ABA漏洞。 ABA问题的解决思路就是使用版本号。在变量前面追加版本号,每次变量更新的时候把版本号加一,那么A-B-A就变成了1A-2B-3C。JDK的atomic包里提供了一个类AtomicStampedReference来解决ABA问题。这个类的compareAndSet方法作用是首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。 volatile: volatile来保证可见性,当一个变量被volatile修饰后,表示着线程本地内存无效,当一个线程修改共享变量后他会立即被更新到主内存中,当其他线程读取共享变量时,它会直接从主内存中读取。volatile也可以保证线程可见性且提供了一定的有序性,但是无法保证原子性。在JVM底层volatile是采用“内存屏障”来实现的。关于volatile的知识还有很多的,这里就不展开了。先说说什么是有序性、原子性、可见性(上面也有说明): 有序性:即程序执行的顺序按照代码的先后顺序执行。在Java内存模型中,为了效率是允许编译器和处理器对指令进行重排序,当然重排序它不会影响单线程的运行结果,但是对多线程会有影响。 Java提供volatile来保证一定的有序性。最著名的例子就是单例模式里面的DCL(双重检查锁)。 原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。原子性就像数据库里面的事务一样,他们是一个团队,同生共死。 在单线程环境下我们可以认为整个步骤都是原子性操作,但是在多线程环境下则不同,Java只保证了基本数据类型的变量和赋值操作才是原子性的(注:在32位的JDK环境下,对64位数据的读取不是原子性操作*,如long、double)。要想在多线程环境下保证原子性,则可以通过锁、synchronized来确保。JDK里面提供了很多atomic类,AtomicInteger,AtomicLong,AtomicBoolean等等。 工具类 同步容器(已过时) 同步容器的工具有Vector、HashTable、Collections.synchroniedXXX()。 并发容器(JUC) ConcurrentHashMap ConcurrentHashMap在jdk1.6中 segment分段锁,读写锁。缺点:弱一致性。 CopyOnWriteArrayList Volative 保证可见性,读写锁。缺点:内存占用,弱一致性 JUC同步器 AQS(这个知识点到时候另行分析) 总结 1、总体来说线程安全在三个方面体现: 原子性:提供互斥访问,同一时刻只能有一个线程对数据进行操作,(atomic,synchronized)。 可见性:一个线程对主内存的修改可以及时地被其他线程看到,(synchronized,volatile)。 有序性:一个线程观察其他线程中的指令执行顺序,由于指令重排序,该观察结果一般杂乱无序,(happens-before原则)。 2、要知道确保线程安全作用是什么,无非就是想让程序按照我们预期的行为去执行。 3、确保线程安全的方法除了上面几种方式还有很多的,我们在实战中可以一步步去发现。
编辑于 2022-04-29 09:14:06 回复(6)
举个简单的例子,索引就好比是一本书的目录,如果给书本排好了目录,那么只需要根据书本的目录,就可以定位到某个知识点的页码,而不用逐页逐页地查找,极大的节省查找书本内容的时间。 索引的好处: 1.能够提高数据的查询性能。 2.能够提高数据分组、数据排序的性能。 索引的缺点: 1.索引需要占用一定的存储空间 2.对数据表的数据进行增、删、改、查时,MySQL内部需要对索引进行动态维护。
发表于 2022-05-08 14:56:41 回复(0)
索引可以提高搜索速度,但是由于数据要多一个索引,会增加内存的消耗,同时也会降低写入数据的速度
发表于 2022-04-24 15:10:17 回复(2)
1.利用锁机制synchronized和Lock 2.使用volatile修饰共享变量,保证可见性 3.使用本地存储ThreadLocal 4.使用不可变量,即常量
编辑于 2022-04-20 14:46:23 回复(4)
MySQL索引是一种帮助快速查找数据的数据结构,可以把索引理解为书的目录。优点:通过索引能够提高检索数据的效率 缺点:索引会增加存储压力,并且新增数据需要同步维护索引
发表于 2022-05-05 10:20:47 回复(0)
索引使用的数据结构是B+树,发生IO的次数少,在大数据量的查询中,使用索引可以加快检索的效率,但是索引在一定情况下会失效,最后还是走了全文检索等...
发表于 2022-04-26 18:16:52 回复(0)
MySQL的索引分类: 存储类型主要是 B+树(B树的改进),Hash(不适合范围查询 容易产生Hash冲突 精确匹配速度快) 字段特性: 主键索引 唯一索引 联合索引 普通索引 物理存储:聚簇索引 二级索引 MySQL的索引是一种帮助我们快速查询数据的数据结构,B+树非叶子节点不存储数据,叶子节点存储数据 帮助我们加快查找速度,减慢了增删改的速度,占用额外的空间进行索引的维护
编辑于 2024-04-03 16:36:53 回复(0)
1、索引是一种用来快速搜索的数据结构,MySQl中主要是B+树。 2、索引的好处:1提高检索速度.2、可以设置唯一索引,保证数据的唯一性 3、索引的坏处:1、索引占用物理内存2、索引的设置和维护消耗大3、需要频繁更新的字段不应设置索引,需要查询的可以设置索引 4、索引的种类:普通索引、唯一索引、主键索引、外键索引、全文索引、复合索引
发表于 2023-03-23 14:08:21 回复(0)
索引是一个单独的、存储在磁盘上的数据库结构,包含着对数据表里所有记录的引用指针。使用索引可以快速找出在某个或多个列中有一特定值的行,所有MySQL列类型都可以被索引,对相关列使用索引是提高查询操作速度的最佳途径。 索引是在存储引擎中实现的,因此,每种存储引擎的索引都不一定完全相同,并且每种存储引擎也不一定支持所有索引类型。MySQL中索引的存储类型有两种,即BTREE和HASH,具体和表的存储引擎相关。MyISAM和InnoDB存储引擎只支持BTREE索引;MEMORY/HEAP存储引擎可以支持HASH和BTREE索引。 索引的优点主要有以下几条: 通过创建唯一索引,可以保证数据库表中每一行数据的唯一性。 可以大大加快数据的查询速度,这也是创建索引的主要原因。 在实现数据的参考完整性方面,可以加速表和表之间的连接。 在使用分组和排序子句进行数据查询时,也可以显著减少查询中分组和排序的时间。 增加索引也有许多不利的方面,主要表现在如下几个方面: 创建索引和维护索引要耗费时间,并且随着数据量的增加所耗费的时间也会增加。 索引需要占磁盘空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果有大量的索引,索引文件可能比数据文件更快达到最大文件尺寸。 当对表中的数据进行增加、删除和修改的时候,索引也要动态地维护,这样就降低了数据的维护速度。
发表于 2022-08-21 17:10:37 回复(0)
MySQL索引可以帮助SQL语句快速查找到数据,它底层数据结构是B+Tree;优点是查询速度快,修改数据慢;所以在使用索引前,需要注意以下原则:索引最左匹配原则;频繁改动的数据表少用索引;以及like,is null,函数等应用
发表于 2022-08-18 16:43:06 回复(0)
两个或两个以上线程为争夺资源而造成僵局的一种情况就是死锁,死锁产出的四个条件分别是:互斥、环路等待、请求与保持、不可剥夺
编辑于 2022-08-16 09:16:30 回复(0)
MYSQL索引分为普通索引,唯一索引,复合索引,主键索引,外键索引,全文索引。 创建索引的优点是: 1. 加快检索效率 2. 加速排序和分组的速度 缺点: 1. 增加存储资源的消耗 2. 增大了增删改维护的成本 。
发表于 2022-05-12 20:31:39 回复(0)
mysql索引能够帮助快速定位查找的数据,提高了查询的效率。但是索引的创建和维护需要耗费时间,而且占用物理空间。
发表于 2022-05-10 14:07:20 回复(0)
Mysql的索引是通过不同的数据结构实现,常见有B+tree、B-Tree、Hash等等,主要目的是类似书籍的目录一样方便快速查找,避免全表扫描,加快执行效率。坏处:每一个索引就是对应存储,如果一个表索引比较多,修改时会多个索引结构都需要修改,影响执行效率
发表于 2022-05-10 13:48:10 回复(0)
优点:索引可以加快检索效率,也可用于排序和分组操作的加速。 缺点:需要大量的存储资源和时间进行对索引进行动态的维护。
发表于 2023-04-05 09:15:26 回复(0)
索引是用于优化大量数据的查询速度,一般情况下需要添加索引的字段是在where条件后面选择,在MySQL5.5以后,索引的主要结构是B+树,这种数据结构更适合存储.索引的分类有普通索引,主键索引,唯一索引,联合索引.当多个字段需要被查找时可以考虑使用联合索引.使用索引的时候要注意索引失效的情况:进行<或>判断时不会走索引,or判断时,如果两个字段其中有一个没有索引,那么都不会走索引,使用联合索引时要注意最左前缀法则,也就是从最左边开始,不可以跳过,否则会使后面的索引都失效.
发表于 2023-02-28 19:40:50 回复(0)
(1)索引是从数据库表中筛选出一条或多条记录的结构 (2)索引的优点:大大提高查询速度、加快表的连接速度、将随机I/O变为顺序I/O (3)索引的缺点:存储索引需要空间、维护索引需要时间
发表于 2023-02-16 21:22:43 回复(0)
● MySQL的索引可以比作是书的目录,通过索引快速找到数据所在的位置 ● MySQL常用的InnoDB引擎使用的索引数据结构是B+Tree,按索引存储形式可以分为聚集索引和二级索引,聚集索引叶子节点保存数据,二级索引叶子节点关联主键 ● 索引主要有普通索引、唯一索引、主键索引、外键索引、全文索引、复合索引几种 ● 好处 ○ 提高了数据检索效率,降低了数据库io时间 ○ 索引列是有序的,降低了数据排序时的成本 ● 坏处 ○ 建立索引需要占用空间 ○ 降低了增删改的效率,因为需要维护索引列
发表于 2023-02-09 13:48:01 回复(0)