二:理解数据页
1. 什么是数据页
一般来说,高效管理大块的资源或数据会按照一定的粒度进行划分。例如Windows的内存管理是按照内存页(4k)来划分的。言下之意就是SQLSERVER是按照mdf来划分管理的,也是按照数据页(8k)来划分的。画一张图,大概是这样的。
那么如何验证这个结论呢?刚才说了,数据都在数据页上。我们只需要获取一些数据并将其提取到指定的数据页上即可。这里使用的是SQLServer 2019。
创建数据库MyTestDBGOUSE MyTestDB;GOIF OBJECT_ID('person') IS NOT NULL DROP TABLE person;CREATE TABLE person( id INT IDENTITY, name CHAR(5));GOINSERT INTO dbo.person( name ) VALUES ('john');INSERT INTO dbo.person( 姓名) VALUES ('玛丽');
2. 寻找数据所在的数据页
刚才图中提到,mdf是由无数个数据页组成的,那么如何找到person表所在的数据页呢?事实上,微软提供了一个dbcc ind命令,可以帮助我们获得洞察。同时,请记住以3604 标记开头,以便在控制台上显示输出而不是默认的错误日志。这个命令的使用方法可以查看官方文档。
DBCC TRACEON(3604)DBCC IND(MyTestDB,人,-1)
从输出结果来看,有两条记录。第一个是PagePID=41是IAM数据页,PagePID=280是我们的person表记录所在的数据页号。也就是说person表记录在mdf文件中的偏移量为0n280 * 0n8192的位置,使用WinDbg计算出来是0x00230000。
0:090? 0n280 * 0n8192求表达式: 2293760=00000000`00230000对吗?您可以使用WinHex来验证它。为了避免进程占用,先把MyTestDB下线,最后记得重新上线。
更改数据库MyTestDB 设置离线更改数据库MyTestDB 设置在线
从WinHex来看,确实是在数据页偏移0x00230000处。
3. 如何从内存中看到数据页
我们刚才看到的数据页只是在物理硬盘上,但是数据页与数据页之间的逻辑关系必须使用一定的数据结构来承载在内存中。接下来我们看看这个数据页是如何映射到SQLSERVER进程内存在哪里的? Microsoft提供了DBCC PAGE命令来查看指定数据页的详细信息。
DBCC TRACEON(3604)DBCC PAGE(MyTestDB,1,280,2)输出结果如下:
DBCC执行完成。如果DBCC 输出错误消息,请联系您的系统管理员。 PAGE: (1:280)BUFFER:BUF @0x000002B41104F480bpage=0x000002B3F0632000 bPmmpage=0x0000000000000000 bsort_r_nextbP=0x000002B41104F3D0b sort_r_prevbP=0x0000000000000000 bhash=0x0000000000000000 bpageno=(1:280)bpart=1 ckptGen=0x0000000000000000 bDirtyRefCount=0bstat=0x9 brerferences=0 0bUse 1=12454 bstat2=0x0 博客=0x15ab215absampleCount=0 bIoCount=0 resPoolId=0bcputicks=0 bReadMicroSec=182 bDirtyContext=0x000000000000000bDbPageBroker=0x0000000000000000 bdbid=10 bpru=0x000002B3FA708040PAGE EADER:Page @0x000002B3F0632000m_pageId=(1:280) m_headerVersion=1 m_type=1m_typeFlagBits=0x0 m_level=0 m_flagBits=0x8200m_objId (AllocUnitId.idObj)=179 m_indexId (AllocUnitId.idInd)=256 Metadata: AllocUnitId=72057594049658880 Metadata: PartitionId=72057594043170816 Metadata: IndexId=0Metadata: ObjectId=5815771 10 m_prevPage=( 0:0) m_nextPage=(0:0)pminlen=13 m_slotCnt=2 m_freeCnt=8060m_freeData=128 m_reservedCnt=0 m_lsn=(37:584:3)m_xactReserved=0 m_xdesId=(0:0) m_ghostRecCnt=0m_tornBits=-116446693 DB Frag ID=1 分配StatusGAM (1:2)=已分配SGAM (1:3)=未分配P FS (133 3601)=0x41 已分配50_PCT_FULLDIFF (1:6)=已更改ML (1:7)=未记录最小数据:内存转储@0x000000F840DF8000000000F840DF8000: 01010000 00820001 00000000 00000d00 00000000 ...000 000F 840DF8014: 00000200 b3000000 7c1f8000 18010000 01000000 . |.000000F840DF8028: 25000000 48020000 03000000 00000000 00000000 %.H..000000F840DF803C: 1b2a0ff9 00000000 00000000 0 0000000 00000000 。 *...000000F840DF8050: 00000000 00000000 00000000 00000000 10000d00 .000000F840DF8064: 01000000 6a6f686e 20020000 1000 0 d00 02000000 .约翰.000000F840DF8078: 6d617279 20020000 00002121 21212121 21212121玛丽.!000000F840DF808C: 21212121 21212121 2121 2121 21212121 21212121 !!!000000F840DF80A0: 21212121 21212121 21212121 21212121 21212121 !!!000000F840DF9FF4: 21212121 21212121 700060 00!p.`.OFFSET TABLE:Row - 偏移量1 (0x1) - 112 (0x70) 0 (0x0) - 96 (0x60) DBCC 执行已完成。如果DBCC 输出错误消息,请联系您的系统管理员。完成时间: 2022-12-30T17:48:20.5466040+08:00 从上面的Memory Dump部分可以看到,数据在进程内存中的000000F840DF8064 ~ 000000F840DF8078范围内。这里要吐槽的是,内存地址是按照big endian布局的,看起来很不习惯,可以使用windbg以little-endian布局来显示。
0:116 dp 000000F840DF8064000000f8`40df8064 6e686f6a`00000001 000d0010`00000220000000f8`40df8074 7972616d`00000002 21210 000`00000220000000f8`40df8084 21212121`21212121 21212121`21212121000000f8`40df8094 21212121`21212121 21212121`2121212100000 0 f8`40df80a4 21212121`21212121 21212121`21212121000000f8`40df80b4 21212121`21212121 21212121` :01 0-1010 喜欢玩windbg的朋友肯定会希望获得对sqlserver的汇编级别的深入了解。比如sqlserver中sql请求的执行流程是怎样的?其实很简单。我们可以这样处理,用ba在john的内存地址上设置一个硬件断点,即ba r4 000000f840df8064+0x4,然后在SSMS上执行一条SELECT * FROM person语句,因为如果我们要提取自然会命中约翰。
本文采摘于网络,不代表本站立场,转载联系作者并注明出处:https://www.iotsj.com//kuaixun/3912.html
用户评论
SQL SERVER 数据页的优化,太重要了!提升查询效率的关键一步!
有18位网友表示赞同!
终于看到一篇讲 SQL SERVER 数据页的,太棒了!期待了解更多!
有18位网友表示赞同!
一直对 SQL SERVER 数据页不太了解,这篇文章解释得非常清楚!
有9位网友表示赞同!
数据页优化,必须得掌握!
有15位网友表示赞同!
SQL SERVER 数据页,影响查询速度的关键因素!
有10位网友表示赞同!
数据页的优化,对于提升 SQL SERVER 性能至关重要!
有10位网友表示赞同!
SQL SERVER 数据页的知识,学习起来很枯燥,但是非常重要!
有11位网友表示赞同!
SQL SERVER 数据页优化,提高数据库性能的关键!
有18位网友表示赞同!
数据页优化,是 SQL SERVER 调优中的一个重要环节!
有20位网友表示赞同!
这篇文章对 SQL SERVER 数据页的讲解非常透彻!
有6位网友表示赞同!
SQL SERVER 数据页,对于数据库性能有很大影响!
有17位网友表示赞同!
学习 SQL SERVER 数据页的优化,很有必要!
有16位网友表示赞同!
SQL SERVER 数据页的优化,是一个复杂的过程!
有12位网友表示赞同!
数据页的优化,需要深入理解 SQL SERVER 的底层机制!
有9位网友表示赞同!
终于找到一篇关于 SQL SERVER 数据页的干货文章!
有10位网友表示赞同!
SQL SERVER 数据页优化,是一个值得深入研究的领域!
有6位网友表示赞同!
数据页的优化,可以有效提高数据库的查询效率!
有12位网友表示赞同!
SQL SERVER 数据页优化,需要掌握一些技巧和方法!
有14位网友表示赞同!
这篇文章对 SQL SERVER 数据页的介绍很实用!
有13位网友表示赞同!
数据页的优化,是提升 SQL SERVER 性能的重要手段!
有11位网友表示赞同!