假设表中有20条记录,正常设置ID为主键,自增,+1设置1:(默认)按照ASC升序
是不是理解为存储的时候按照1——20?设置2:如果将主键改为DESC降序
存储的时候是不是20——1?-----弱弱的分割线-----查找第5条记录
设置1:查找20——6,不是,跳过,——5正确。
设置2:查找1——4,不对,跳过,——5正确。是这个运行机制么……?
如果是的话,数据量很大的情况下,设置2要比设置1好?B树结构,20条记录理解为20个页
那么设置2需要跳过的只是4个页
而设置1需要跳过15个页-----弱弱的分割线-----今天突然很2B地冒出这个想法,求解救!
是不是理解为存储的时候按照1——20?设置2:如果将主键改为DESC降序
存储的时候是不是20——1?-----弱弱的分割线-----查找第5条记录
设置1:查找20——6,不是,跳过,——5正确。
设置2:查找1——4,不对,跳过,——5正确。是这个运行机制么……?
如果是的话,数据量很大的情况下,设置2要比设置1好?B树结构,20条记录理解为20个页
那么设置2需要跳过的只是4个页
而设置1需要跳过15个页-----弱弱的分割线-----今天突然很2B地冒出这个想法,求解救!
这也是索引扫描 和 索引查找不一样的地方哦。不过对于索引树的遍历ASC/DESC确实有他的意义,尤其当遇到联合索引时。
先感谢两位,讨论讨论。我指的就是在B树最上面定位/遍历的过程
如果是T级数据的时候,这个定位是从前往后还是从后往前,是否存在意义呢……
同等条件下(索引、分区……等等所有条件),数据库越大速度也就越慢,也许也是因为这个原因咩?按照实际业务操作中,“查询”这个功能,在大多数情况下,都是从新往旧,也就是说最好是定义为DESC?
设置1:查找20——6,不是,跳过,——5正确。
设置2:查找1——4,不对,跳过,——5正确。这个是局部扫描操作,Seek查找5是从根/中间级/叶级直接命中数据,Seek速度取决于树的深度,当然表越大越慢。如果是范围查找比如7-15,取决于索引顺序,如果是DESC命中15开始向前局部扫描,如果是ASC则命中7开始向前局部扫描,索引顺序不会影响Scan/Seek的速度。按照实际业务操作中,定义为DESC是有问题的,每条数据都是插入,假设每页2条数据,每次插入两条,就不考虑页拆分了:
2,1 <-> 4,3 <-> 6,5 <-> 8,7 <-> 10,9
进行局部扫描的时候,导致磁头疯狂的往返移动,比如查找4-8:8,7同一页中是向前的,下一页6,5物理位置和逻辑位置相反,磁头回撤。重建索引整理碎片之后的情形:
10,9 <-> 8,7 <-> 6,5 <-> 4,3 <-> 2,1
索引分成聚集索引和非聚集索引。主键通常是聚集索引,也可能是非聚集索引。
假如有10000条记录,1000条记录一个叶子,就是有10个叶子。
如果要找3210这条记录,无论是ASC还是DESC,应该都是一样的速度找到3001-4000这个叶子。
而在叶子中,则是顺序查找的,所以,ASC排序会比DESC快一点。但如果是找4000这条记录,则DESC排序会快一点,因为第一条记录就是了。如果经常读取最后一条记录,则DESC会快一点。
聚集索引和非聚集索引的差别在于范围读取,因为聚集索引会将记录连续存储,所以可以连续读取。而非聚集索引不一定是连续存储,所以读取时,磁头可能会四处移动的。
先谢谢Vidor和zbdzjx两位我去专家问答那问了一下邹建大神,回答很简单
每级索引中的页均被链接在双向链接列表中,所以不存在需要严格区分ASC和DESC的情况
也就是说无论ASC/DESC,数据库会优先使用效率较高的链接?
(好像应该是这样理解)
你的意思看懂了。
主键应该就是设置为ASC,避免磁头往返移动。
扩展一下,索引的ASC/DESC设置最好与主键一致,也就是ASC,也是避免磁头往返移动?
是这么个说法?
按照双向链接列表这个概念,其实应该不存在ASC/DESC这个问题,数据库自动找到最快的检索方案。--------结论一下--------
按照:每级索引中的页均被链接在双向链接列表中,所以不存在需要严格区分ASC和DESC的情况
1、不存在ASC/DESC的搜索速度问题,数据库会使用最佳搜索方案。
过程可能包括根节点、页节点……等等
2、ASC与DESC的设置,应该是用ASC,避免磁头的往返移动。理解不知道对不对。
容我暂不结贴,再次思考思考。
假如有10000条记录,1000条记录一个叶子,就是有10个叶子。
在第一级,有一个节点,存放(1-10000),有两个指针,指向两个节点。
第二级,两个节点(对应上一级),分别存放(1-5000)、(5001-10000),分别有五个指针,指向五个叶子。
第三级,有两组,每组五个叶子,对应上一级的两个节点,存放(1-1000)、(1001-2000)……(9001-10000)
所以,无论ASC/DESC,都可以很快的查找到相应的叶子。
而在叶子中,是按顺序存放的,如ASC则存放1-1000;如DESC则存放1000-1。搜索时,也是按顺序一个一个找的。(这一级不会再往下分级了。)
所以,1000条记录以内,索引就一级,就是按顺序从前往后找;1000~1000000条记录,是两级,就是一个节点加1000个叶子,由这个节点来确定在哪个叶子里,再在叶子里按顺序查找……
因此,在从节点找到叶子的过程中,和ASC/DESC应该没多大关系。只是在叶子中的1000条记录时搜索时,才有关系。但实际过程中,从1000条记录里查找一条记录,应该是很快的。只有从索引中读取大量数据时,ASC/DESC才会有影响。
仔细看了两遍,按照里面说的1、最底层存储的量是大致固定的(比如1000条),数据库的性能在搜索1000条记录时,使用ASC/DESC,用户体验上是没有区别的。
(如果再考虑双向链接列表的话,就更加没区别)
(这个1000应该需要扩大,毕竟MSSQL的性能还是不错的,具体数字应该是属于非常快的处理范围内。)2、应该考虑的是数据越多,分支节点(或者说分支的层数)就越多。
这也是造成“数据越大搜索越慢”的原因。
对于这个情况,我们使用分区的办法,降低每个区的数据量——也就是降低分支层数,这样来达到提高速度。这样理解?
谢谢,非常感谢。
大致有个了解了,要进一步学习就真的需要实际测试分析了。对于主键的ASC/DESC关注点应该是在于:
实际操作中磁头的往返移动及其所产生碎片对物理层的影响;而不是查找的效率问题。感谢!
非常感谢各位的释义,觉得自己升华了~