其中一些解释可能会涵盖您已经知道的内容,但完整的细节可能会对未来的读者有所帮助。
服务器很可能只获取所需的行。但是,这可能会受到数据存储方式的影响。例如,InnoDB 引擎通常存储大数据(如TEXT
s 和BLOB
s 离页,因此如果不需要,可能不会获取这些数据。
我想我需要在这里澄清一下,所以如果我从你的问题中遗漏了什么,请纠正我。首先,最好只返回您需要的列并列出所有列而不是选择*
更快。与 #1 一样,选择其他列会有多大的不同取决于。选择大列(如TEXT
s 或BLOB
s)通常比小列更昂贵。
我不是 100% 确定你在这里的意思,但我想我可以回答这个问题。如果您有类似的查询,则类似SELECT c1, c2, c3 FROM table WHERE c1 = 1 AND c2 = 2
的索引(c1,c2,c3)
可能是最佳的;查询需要的所有列都在索引中,因此服务器不需要查找完整的数据行。c1
、c2
或c3
是否包含在任何其他索引中都没有关系。
在您的问题中,您说的是a clustered index db is not storing the rowId anymore
,这并不完全正确。
假设rowId
是数据的唯一标识符,可能是数字标识符:
在非集群数据库表中,所有索引都将某些列连接到物理数据位置。在主索引的情况下,这看起来像rowId -> data location
。二级索引可能看起来像column 1 -> column 2 -> data location
. 为了获取任何其他数据,服务器然后根据物理位置查找数据。
在聚簇表中,物理数据基本上就是主索引。主索引看起来像rowId -> data
,二级索引看起来像column 1 -> column 2 -> rowId
。
对于非聚集表,完整的查找路径看起来像rowId -> data location -> data
使用主索引和column 1 -> column 2 -> data location -> data
二级索引。
对于聚簇表,它看起来像rowId -> data
主索引和column 1 -> column 2 -> rowId -> data
二级索引。
因此,为了更正本节开头的引用,真正“存储”的唯一索引rowId
是聚簇表上的二级索引。
虽然聚簇表上的二级索引查找比非聚簇表慢,但如果您使用短主键,差异通常可以忽略不计。聚集表的主要好处之一是主索引查找速度更快,因此如果您主要使用主键查找,它们是有益的。
回应 KutaBeach 的评论:
获取不需要的列没有帮助。当服务器需要获取数据以获取不在索引中的行时,它并不总是获取该行的所有数据。一些存储配置将一些数据存储在主行之外,因为它可能非常大,否则会影响性能。一个示例可以是TEXT
每行长度为 65535 个字符的列。TEXT
如果存储引擎将该数据存储在页面外,那么在不需要列的情况下 从行获取数据会快得多。
听起来当您说 时rowId
,您的意思是行的物理地址,而不是分配给每行的唯一编号。在这种情况下,您是正确的,只有聚集表上的二级索引不存储rowId
; 所有其他索引都存储rowId
. 然而,这并不是因为数据可以或不能移动;表中的数据可以随时移动,在这种情况下,索引会更新以反映移动。在 MySQL 中,aPRIMARY INDEX
基本上只是表的主索引。它与索引几乎相同,UNIQUE
因为它强制值是唯一的,唯一的区别是它用作表的主键。非聚集索引确实包含每个rowId
.