Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql RID查找-逻辑搜索_Sql_Sql Server_Indexing_Sql Execution Plan_B Tree - Fatal编程技术网

Sql RID查找-逻辑搜索

Sql RID查找-逻辑搜索,sql,sql-server,indexing,sql-execution-plan,b-tree,Sql,Sql Server,Indexing,Sql Execution Plan,B Tree,例如,我们有一个包含聚集索引table1(col1 int,col2 int,col3 int)的表,为col1定义了聚集索引,为col2定义了非聚集索引,我们从table1中编写query-select*,其中col2='some value'-优化器用于非聚集索引查找,获取特定行并转到聚集索引以获取非聚集索引中未包含的其余数据(在本例中,执行键查找以获取col3)。键查找本质上是基于在叶级非聚集索引中找到的聚集索引值的聚集索引查找 当表上没有聚集索引,但有非聚集索引时会发生什么?我知道它将执

例如,我们有一个包含聚集索引table1(col1 int,col2 int,col3 int)的表,为col1定义了聚集索引,为col2定义了非聚集索引,我们从table1中编写query-select*,其中col2='some value'-优化器用于非聚集索引查找,获取特定行并转到聚集索引以获取非聚集索引中未包含的其余数据(在本例中,执行键查找以获取col3)。键查找本质上是基于在叶级非聚集索引中找到的聚集索引值的聚集索引查找


当表上没有聚集索引,但有非聚集索引时会发生什么?我知道它将执行RID查找,但这在逻辑上是如何工作的?聚集索引值将使用b-树搜索找到,因为我们所有的行都是按特定顺序排列的,但如何在没有任何特定顺序的堆表中找到聚集索引值呢?根据我的理解,当我们在非聚集索引中找到行(这有非聚集索引键+rowid)时,我们需要扫描整个堆表以在那里找到此rowid,因为我们在那里没有任何顺序,并且无法使用b-树导航此行,是否正确?

这是一个概念性的解释。数据库在数据页上存储行,而数据页又存储行。
rid
根据“物理”位置直接标识行的位置。实际上,数据页是“逻辑”的,因为它可以在内存中或磁盘上

数据库不需要通过面向用户的索引来标识行的位置。它需要识别页面,然后识别页面上的偏移量。
rid
包含关于哪一页和偏移量的信息。因此,页面管理系统可以直接从rid中找到它需要的页面

不需要扫描任何内容来查找行

也就是说,数据库必须做一些事情,例如:

  • 数据页是否在页缓存中?如果没有,那就去拿
  • 内存中的页面是否已修改?如果不允许,则允许脏读
  • 这排锁上了吗

在理解数据库如何工作时,常常忽略存储层的管理。就每天编写查询而言,页面管理似乎很有效。然而,访问一行并不是一个简单的操作。数据库在ACID属性、可靠性和可扩展性方面的许多强大功能都依赖于存储管理层。

举个例子可能会有所帮助。下面创建一个堆并向其中插入几行

CREATE TABLE Demo(X CHAR(1));

INSERT INTO Demo VALUES ('A'), ('B');
然后可以使用以下命令查看RID

SELECT X,
       %%physloc%% as rid, 
       sys.fn_PhysLocFormatter(%%physloc%%) as formatted
FROM Demo
这对我来说是回报

+---+--------------------+-----------+
| X |        rid         | formatted |
+---+--------------------+-----------+
| A | 0xE700000001000000 | (1:231:0) |
| B | 0xE700000001000100 | (1:231:1) |
+---+--------------------+-----------+
RID是一个8字节的二进制值,由三个组件串联而成<代码>文件号:页码:SlotNumber

每个文件被分成8KB的页面,编号从0开始,因此计算给定页码的文件偏移量非常简单。第231页是从文件中字节偏移量1892352开始的8KB部分(
231*8192

要定位属于RID
1:231:1
的行,只需从缓冲区管理器(如果需要,缓冲区管理器将从光盘读取)获取相关页面(
1:231
),然后转到页面上的第二个插槽(插槽编号从0开始)


每个数据页的页脚中都有一个,给出页上每一行的行偏移量。

rowid通常包括要在表空间中读取的逻辑磁盘段的信息。这意味着从堆中检索行只需要一个I/O操作。此外,由于低级别缓存,I/O段可能已经在内存中,因此大多数时候它几乎是瞬时的。这就是为什么高端数据库(Oracle、DB2、PostgreSQL)使用堆模型而不是聚集索引模型(速度较慢)的原因。感谢您的回复,但我仍然不明白RDBMS如何快速理解需要读取的页面?例如,我们已经在缓冲池中有了这个特定的页面,SQL server如何快速搜索这个页面?