mysql同样的结构和数据,为什么innodb比myisam查询速度慢了30多倍,myisam和innodb锁

文章 3年前 (2021) admin
0

Q1:mysql myisam与innodb哪个速度更快,优缺点又是什么

如果你的业务不需要使用到事务,那么使用myisam是最佳考虑,因为myisam不支持事务,有比较好的性能。但是如果你的业务必须要使用到事务,也就是说对数据一致性要求很高的话,需要使用到INODB,由于INODB要使用到锁,因此它的并发能力就差一些,因此性能方面也会差一些祝你愉快,满意请采纳。

Q2:为什么MyISAM会比Innodb的查询速度快

为什么MyISAM会比Innodb的查询速度快?数据块,INNODB要缓存,MYISAM只缓存索引块,  这中间还有换进换出的减少;innodb寻址要映射到块,再到行,MYISAM记录的直接是文件的OFFSET,定位比INNODB要快INNODB还需要维护MVCC一致;虽然你的场景没有,但他还是需要去检查和维护MVCC (Multi-Version Concurrency Control)多版本并发控制 希望对你有帮助

Q3:myisam为什么比innodb快

为什么MyISAM比Innodb快?对于数据块,INNODB应该缓存,MYISAM只缓存索引块,换入换出也有减少;Innodb寻址应该映射到块,然后映射到行。MYISAM直接记录文件的OFFSET,定位比INNODB快。INNODB还需要保持MVCC的一致性。虽然你的场景不存在,但他还是需要检查维护MVCC(多版本并发控制)多版本并发控制,希望对你有帮助。

Q4:请论述下mysql中innodb和myisam的区别和优劣

如果只使用MyISAM表,可以将其设置为可用内存的30-40%。的合理值取决于索引大小、数据量和负载—请记住,MyISAM表使用操作系统的缓存来缓存数据,因此需要为它们留出一些内存,并且在许多情况下,数据比索引大得多。但是,总是有必要检查是否所有的key_buffers都被使用了。myi文件只有1GB,但是key _ buffer设置为4GB。这是浪费。如果你很少使用MyISAM表,保持key_buffer_size低于16-32MB,以适应给磁盘的临时表请求。引  所需。  innodb_buffer_pool_size - 这对Innodb表来说非常重要。Innodb相比MyISAM表对缓冲更  为敏感。MyISAM可以在默认的 key_buffer_size 设置下运行的可以,然而Innodb在默认的  innodb_buffer_pool_size 设置下却跟蜗牛似的。由于Innodb把数据和索引都缓存起来,  无需留给操作系统太多的内存,因此如果只需要用Innodb的话则可以设置它高达 70-80% 的  可用内存。一些应用于 key_buffer 的规则有 -- 如果你的数据量不大,并且不会暴增,那  么无需把  innodb_additional_pool_size - 这个选项对性能影响并不太多,至少在有差不多足够内存  可分配的操作系统上是这样。不过如果你仍然想设置为 20MB(或者更大),因此就需要看一下  Innodb其他需要分配的内存有多少。  innodb_log_file_size 在高写入负载尤其是大数据集的情况下很重要。这个值越大则性能相  对越高,但是要注意到可能会增加恢复时间。我经常设置为 64-512MB,跟据服务器大小而异。  innodb_log_buffer_size 默认的设置在中等强度写入负载以及较短事务的情况下,服务器性  能还可以。如果存在更新操作峰值或者负载较大,就应该考虑加大它的值了。如果它的值设置  太高了,可能会浪费内存 -- 它每秒都会刷新一次,因此无需设置超过1秒所需的内存空间。  通常 8-16MB 就足够了。越小的系统它的值越小。  innodb_flush_logs_at_trx_commit 是否为Innodb比MyISAM慢1000倍而头大?看来也许你忘  了修改这个参数了。默认值是 1,这意味着每次提交的更新事务(或者每个事务之外的语句)  都会刷新到磁盘中,而这相当耗费资源,尤其是没有电池备用缓存时。很多应用程序,尤其是  从 MyISAM转变过来的那些,把它的值设置为 2 就可以了,也就是不把日志刷新到磁盘上,  而只刷新到操作系统的缓存上。日志仍然会每秒刷新到磁盘中去,因此通常不会丢失每秒1-  2次更新的消耗。如果设置为 0 就快很多了,不过也相对不安全了 -- MySQL服务器崩溃时  就会丢失一些事务。设置为 2 指挥丢失刷新到操作系统缓存的那部分事务。  table_cache -- 打开一个表的开销可能很大。例如MyISAM把MYI文件头标志该表正在使用  中。你肯定不希望这种操作太频繁,所以通常要加大缓存数量,使得足以最大限度地缓存打  开的表。它需要用到操作系统的资源以及内存,对当前的硬件配置来说当然不是什么问题了。  如果你有200多个表的话,那么设置为 1024 也许比较合适(每个线程都需要打开表),  如果连接数比较大那么就加大它的值。我曾经见过设置为 100,000 的情况。  thread_cache -- 线程的创建和销毁的开销可能很大,因为每个线程的连接/断开都需要。  我通常至少设置为 16。如果应用程序中有大量的跳跃并发连接并且 Threads_Created 的值  也比较大,那么我就会加大它的值。它的目的是在通常的操作中无需创建新线程。  query_cache -- 如果你的应用程序有大量读,而且没有应用程序级别的缓存,那么这很有  用。不要把它设置太大了,因为想要维护它也需要不少开销,这会导致MySQL变慢。通常设置  为 32-512Mb。设置完之后最好是跟踪一段时间,查看是否运行良好。在一定的负载压力下,  如果缓存命中率太低了,就启用它。  sort_buffer_size --如果你只有一些简单的查询,那么就无需增加它的值了,尽管你有  64GB 的内存。搞不好也许会降低性能

Q5:mysql innodb select count 查询速度慢,该怎么优化,已加二级索引,还是比较慢,400w数据

从MySQL 5.7开始,开发人员改变了InnoDB构建二级索引的方式,采用了自下而上的方法,而不是早期版本中的自上而下的方法。在本文中,我们将通过一个例子来说明如何构建InnoDB索引。最后,我将解释如何为innodb_fill_factor设置一个更合适的值。索引构建过程使用数据在表上构建索引。InnoDB有以下几个阶段:1 .读取阶段(从聚集索引读取和构建二级索引条目)2。合并和分类阶段3。插入阶段(将排序后的记录插入到二级索引中)在5.6版本之前,MySQL通过一次插入一条记录来构建二级索引。这是一种“自上而下”的方法。搜索位置从树的根(顶部)开始,到达叶页面(底部)。记录被插入到光标指向的叶页面上。查找插入位置和拆分合并工作面的成本很高。从MySQL 5.7开始,添加索引期间的插入阶段使用“排序索引构建”,也称为“批量索引加载”。在这种方法中,索引是从下往上构造的。也就是说,首先构建叶页面(底部),然后非叶级别到达根(顶部)。在这些情况下使用排序索引构建示例:alter table t1添加索引(或创建索引)ALTER table t1添加全文索引器table t1添加列,algorithm=inplaceopimize t1对于最后两个用例,ALTER创建一个中间表。中间表索引(主索引和次索引)是使用排序索引构造构建的。该算法在0级创建一个页面,并为此页面创建一个光标。将光标放在第0层插入页面,直到整个页面填满,创建一个同级页面(不要将其插入同级页面),为当前整个页面创建一个节点指针(子页面中最小的键,子页面编号),并将节点指针插入上层(父页面)。在更高层次上,检查光标是否已经定位。如果没有,请为此级别创建一个父页面和光标,并在父页面中插入一个节点指针。如果父页面已满,请重复步骤3、4、5和6。现在插入同级页面,并将光标指向同级页面。在所有插入的末尾,每一级的光标指向最右边的页面。提交所有游标(这意味着提交小事务来修改页面并释放所有锁存)。为了简单起见,上面的算法跳过了关于压缩页面和BLOB(外部存储的BLOB)处理的细节。从下到上构造索引为简单起见,假设子页和非子页中允许的最大记录数为3create tablet1 (a int主键,b int,c blob);插入t1值(1,11," hello 111 ");插入t1值(2,22," hello 222 ");插入t1值(3,33," hello 333 ");插入t1值(4,44," hello 444 ");插入t1值(5,55," hello 555 ");插入t1值(6,66," hello 666 ");插入t1值(7,77," hello 777 ");插入t1值(8,88," hello 888 ");插入t1值(9,99," hello 999 ");插入t1值(10,1010," hello 101010 ");更改表t1添加索引k1(b);InnoDB将主键字段追加到辅助索引中。二级索引k1的记录格式为(b,a)。整理阶段结束后,记录为:(11,1)、(22,2)、(33,3)、(44,4)、(55,5)、(66,6)、(77,7)、(88,8)、(99,9)。在0级(叶级)创建页面在页面上创建光标。所有插入内容都将转到此页面,直到它被箭头填充,以显示光标当前指向的位置。它目前在第5页,下一次插入将转到这一页。仍然有两个空闲槽,所以插入记录(22,2)和(33,3)非常简单。对于下一条记录(44,4),页码5已满(假设上面提到的最大记录数为3)。这是第一步。页面填充期间的索引构造创建一个兄弟页面,页码6不要插入兄弟页面提交光标处的页面,即迷你事务提交、释放闩锁等。作为提交的一部分,创建一个节点指针,并将其插入[当前级别1](即级别1)的父页面。节点指针的格式(子页中的最小键,子页号)。第5页的最小键是(11,1)。在父级((11,1),5)插入记录。
1级的父页面还不存在,MySQL创建了7号页面,光标指向7号页面。将((11,1),5)插入第7页现在,返回到第0级,并创建从第5页到第6页的链接,反之亦然。0级光标现在指向页码为6的同级页面。在第6页插入(44,4)。接下来的插入-(55,5)和(66,6)-非常简单。他们翻到第六页。插入记录(77,7)类似于(44,4),只是父页(页码7)已经存在,并且它有空间容纳两个以上的记录。首先,将节点指针((44,4),8)插入第7页,然后将(77,7)记录到同一级别的8页中。插入记录(88,8)和(99,9)很容易,因为第8页上有两个空闲槽。下一个插入(1010,10)。将节点指针((77,7),8)插入第1级(页码)的父页。 7)。MySQL 在 0 级创建同级页码 9。将记录 (1010,10) 插入第 9 页并将光标更改为此页面。以此类推。在上面的示例中,数据库在 0 级别提交到第 9 页,在 1 级别提交到第 7 页。我们现在有了一个完整的 B+-tree 索引,它是自下至上构建的!索引填充因子全局变量 innodb_fill_factor 用于设置插入 B-tree 页中的空间量。默认值为 100,表示使用整个业面(不包括页眉)。聚簇索引具有 innodb_fill_factor=100 的免除项。 在这种情况下,聚簇索引也空间的 1 /16 保持空闲。即 6.25% 的空间用于未来的 DML。值 80 意味着 MySQL 使用了 80% 的页空间填充,预留 20% 于未来的更新。如果 innodb_fill_factor=100 则没有剩余空间供未来插入二级索引。如果在添加索引后,期望表上有更多的 DML,则可能导致业面拆分并再次合并。在这种情况下,建议使用 80-90 之间的值。此变量还会影响使用 OPTIMIZE TABLE 和 ALTER TABLE DROP COLUMN, ALGOITHM=INPLACE 重新创建的索引。也不应该设置太低的值,例如低于 50。因为索引会占用浪费更多的磁盘空间,值较低时,索引中的页数较多,索引统计信息的采样可能不是最佳的。优化器可以选择具有次优统计信息的错误查询计划。排序索引构建的优点没有页面拆分(不包括压缩表)和合并没有重复搜索插入位置插入不会被重做记录(页分配除外),因此重做日志子系统的压力较小缺点ALTER 正在进行时,插入性能降低 Bug#82940,但在后续版本中计划修复。请点击输入图片描述

Q6:

相关文章