MySQL的索引性能

MySQL的索引性能,mysql,performance,indexing,Mysql,Performance,Indexing,假设我有一个mysql表,在“name”列上有一个索引: 我做这个查询: select * from name_table where name = 'John'; 假设从一个包含100行的表返回5个结果 假设我现在插入100万个新行,其中没有一个名称为John的行,因此表中仍然只有5个John。select语句是否会像以前一样快,插入所有这些行是否会影响索引表的读取速度?索引有自己的“表”,当MySQL引擎确定查找引用索引列时,将在此表上进行查找。它本身并不是一张真正的桌子,但要点是正确的

假设我有一个mysql表,在“name”列上有一个索引:

我做这个查询:

select * from name_table where name = 'John';
假设从一个包含100行的表返回5个结果

假设我现在插入100万个新行,其中没有一个名称为John的行,因此表中仍然只有5个John。select语句是否会像以前一样快,插入所有这些行是否会影响索引表的读取速度?

索引有自己的“表”,当MySQL引擎确定查找引用索引列时,将在此表上进行查找。它本身并不是一张真正的桌子,但要点是正确的

这就是说,它会慢纳秒,但这不是你应该关心的事情

更重要的是,请关注相关数据的索引,因为这些数据对数据库性能的影响更大

要了解更多关于幕后发生的事情,请查询
解释

EXPLAIN select * from name_table where name = 'John';
注意:除了链接中列出的列顺序之外,最好在固定长度的列(
CHAR
)之后再添加可变长度的列(
VARCHAR
),因为在查找过程中,引擎必须查看行、读取列长度,然后向前跳进行查找(请注意,这仅适用于未编制索引的列),或者阅读表declairation,并知道它始终必须查看偏移量为X的列。这在幕后更加复杂,但如果您可以将所有固定长度的列移到前面,您将感谢您自己。基本上:

Indexed columns.
Everything Fixed-Length in order according to the link.
Everything Variable-Length in order according to the link.
索引有自己的“表”,当MySQL引擎确定查找引用了一个索引列时,就会在这个表上进行查找。它本身并不是一个表,但gist会检查出来

这就是说,它会慢纳秒,但这不是你应该关心的事情

更重要的是,请关注相关数据的索引,因为这些数据对数据库性能的影响更大

要了解更多关于幕后发生的事情,请查询
解释

EXPLAIN select * from name_table where name = 'John';
注意:除了链接中列出的列顺序之外,最好在固定长度的列(
CHAR
)之后再添加可变长度的列(
VARCHAR
),因为在查找过程中,引擎必须查看行、读取列长度,然后向前跳进行查找(请注意,这仅适用于未编制索引的列),或者阅读表declairation,并知道它始终必须查看偏移量为X的列。这在幕后更加复杂,但如果您可以将所有固定长度的列移到前面,您将感谢您自己。基本上:

Indexed columns.
Everything Fixed-Length in order according to the link.
Everything Variable-Length in order according to the link.

是的,速度也一样快。

(除了Mike的回答中的精彩点之外…)关于索引(特别是B树索引),我们还应该提出一个重要的观点:

索引中的条目按“顺序”存储

索引的组织方式也允许数据库非常快速地识别索引中包含它正在查找的条目的块(或者如果没有匹配的条目,将包含条目的块)

这意味着数据库不需要查看索引中的每个条目。给定一个类似于您问题中的谓词:

  WHERE name = 'John'
有了一个前导列为
name
的索引,数据库可以消除大量不需要检查的块

索引开头附近的块包含条目
'Adrian'
'Anna'
,在索引的稍晚一点,一个块包含
Caleb
Carl
,在索引
James
Jane
中更长的条目,等等

由于索引的组织方式,数据库有效地“知道”我们要查找的条目不能在这些块中的任何一个(因为索引是有序的,所以值
John
不可能出现在我们提到的那些块中)。因此这些块都不需要检查。(数据库通过非常少量的操作计算出,索引中98%的块可以从考虑中消除

高基数=良好性能

这样做的好处是索引对具有高基数的列最有效。也就是说,列中有大量不同的值,这些值是唯一的或几乎唯一的

这将澄清您所问问题的答案。您可以将巴西人行添加到表中。如果其中只有五行的值为
John
在名称列中,当您执行查询时

  WHERE name = `John`
它的速度也一样快。当你在表中有一千行时,数据库将能够以最快的速度找到你要查找的条目

(随着索引变得越来越大,它确实向索引添加了“级别”,以向下遍历到叶节点……因此,它变得越来越慢,因为只需再进行几次操作。当InnoDB缓冲区缓存太小时,性能真正开始停滞不前,我们不得不等待(相比之下,速度非常慢)将块提取到内存中的磁盘io操作

基数低=性能差

对于基数较低的列,索引的效果要差得多。例如,一个列有两个可能的值,并且值在表中的行之间分布均匀(大约一半的行有一个值,另一半有另一个值)在这种情况下,数据库无法消除98%的块或90%的块。数据库必须费力地遍历索引中的一半块,然后(通常)对基础表中的页面执行查找,以获得其他值f