我在字节当主管:百次面试结果,总结一个刷掉99%求职者的问题!

我一个在大厂当主管的朋友,跟我说:

“现在招性能测试太难了,当然不是说没人干,一开招聘信息就能收到一大把简历,其中不乏学历亮眼、背景出色、简历里各种高并发、大流量的项目经验的人才。

问题在于,当你提出讲一个项目中遇到的性能问题,以及如何分析定位时,却发现绝大多数根本没有遇到过性能问题。

甚至面试了几个高级性能测试工程师,还是发现一旦涉及到性能分析调优,就开始左顾右盼、答非所问。”

“问题的结症在于,大部分面试者参与的性能测试项目就不多,企业又希望招有经验的测试,这本身就存在矛盾!”

我说,你说的情况谁不知道?你不如讲点实际的,讲点经验,性能调优你说怎么弄?

朋友思考了一会说道:“那不如正好聊聊我手上的这个项目,聊聊SQLSERVER数据页!”

“什么是数据页 ”

一般来说,对大块资源或者数据进行高效管理都会按照一定粒度来划分的,比如说 Windows 对内存的管理就是按照 内存页 (4k) 来进行划分,言外之意就是 SQLSERVER 对 mdf 的管理也是按照 数据页 (8k) 来划分的,画个图大概就是这样的。

那如何来验证这个结论呢?刚才也说了数据都在数据页上,我们弄点数据然后在指定的数据页上提取出来就好了,这里用的是 SQLServer 2019

CREATEDATABASE MyTestDBGOUSE MyTestDB;GOIF OBJECT_ID('person') IS NOT NULLDROPTABLE person;CREATETABLE person(idINTIDENTITY,nameCHAR(5));GOINSERT INTO dbo.person( name ) VALUES ('john');INSERTINTO dbo.person( name ) VALUES ('mary');

“寻找数据所在的数据页”

一般来说,对大块资源或者数据进行高效管理都会按照一定粒度来划分刚才图中也说了 mdf 是由无数个 数据页 拼出来的,那如何找到 person 表所在的数据页呢?其实微软提供了一个 dbcc ind 命令可以帮我们洞察出来,同时记得开始3604标记,让输出显示在控制台上,而不是默认的错误日志中,这个命令具体怎么用,大家可以查看官方文档。

DBCCTRACEON(3604)DBCCIND(MyTestDB,person, -1)

从输出看有两条记录,第一个是 PagePID=41 是 IAM 数据页,而PagePID=280 就是我们 person 表记录所在的数据页编号,也就是说 person 表的记录在 mdf 文件偏移为 0n280 * 0n8192 的位置,用 WinDbg 算一下就是 0x00230000 。

0:090> ? 0n280 * 0n8192Evaluateexpression: 2293760 = 00000000`00230000

那是不是呢?可以用 WinHex 验证一下,为了不出现进程占用,先把 MyTestDB 下线了,最后记得再上线即可。

ALTERDATABASE MyTestDB SETOFFLINEALTERDATABASE MyTestDB SETONLINE

从WinHex 上看,果然是在偏移为 0x00230000 这个数据页上。

“如何从内存中看到数据页”

刚才我们看到的数据页只是物理硬盘上的,但数据页和数据页之间的逻辑关系肯定是在内存中用一定的数据结构来承载的,接下来看下这个 数据页 映射到 SQLSERVER 进程内存的哪里呢?微软提供了 DBCC PAGE 命令可以查看指定 数据页 的详细信息。

DBCCTRACEON(3604)DBCCPAGE(MyTestDB,1,280,2)

输出结果如下:

DBCC执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。PAGE: (1:280)BUFFER:BUF@0x000002B41104F480bpage = 0x000002B3F0632000          bPmmpage = 0x0000000000000000       bsort_r_nextbP = 0x000002B41104F3D0bsort_r_prevbP = 0x0000000000000000 bhash = 0x0000000000000000          bpageno = (1:280)bpart = 1                           ckptGen = 0x0000000000000000        bDirtyRefCount = 0bstat = 0x9                         breferences = 0                     berrcode = 0bUse1 = 12454                       bstat2 = 0x0                        blog = 0x15ab215absampleCount = 0                    bIoCount = 0                        resPoolId = 0bcputicks = 0                       bReadMicroSec = 182                 bDirtyContext = 0x0000000000000000bDbPageBroker = 0x0000000000000000  bdbid = 10                          bpru = 0x000002B3FA708040PAGE HEADER: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 = 581577110      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                      Allocation StatusGAM(1:2) = ALLOCATED               SGAM (1:3) = NOT ALLOCATED          PFS (1:1) = 0x41 ALLOCATED  50_PCT_FULLDIFF(1:6) = CHANGED                ML (1:7) = NOT MIN_LOGGED           DATA:MemoryDump @0x000000F840DF8000000000F840DF8000:   01010000 00820001 00000000 00000d00 00000000  ....................000000F840DF8014:   00000200 b3000000 7c1f8000 18010000 01000000  ........|...........000000F840DF8028:   25000000 48020000 03000000 00000000 00000000  %...H...............000000F840DF803C:   1b2a0ff9 00000000 00000000 00000000 00000000  .*..................000000F840DF8050:   00000000 00000000 00000000 00000000 10000d00  ....................000000F840DF8064:   01000000 6a6f686e 20020000 10000d00 02000000  ....john ...........000000F840DF8078:   6d617279 20020000 00002121 21212121 21212121  mary .....!!!!!!!!!!000000F840DF808C:   21212121 21212121 21212121 21212121 21212121  !!!!!!!!!!!!!!!!!!!!000000F840DF80A0:   21212121 21212121 21212121 21212121 21212121  !!!!!!!!!!!!!!!!!!!!...000000F840DF9FF4:   21212121 21212121 70006000                    !!!!!!!!p.`.OFFSETTABLE:Row- Offset                        1 (0x1) - 112 (0x70)                0 (0x0) - 96 (0x60)                 DBCC执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。Completiontime: 2022-12-30T17:48:20.5466040+08:00

从上面的 Memory Dump 区节中可以看到,数据在进程内存的 000000F840DF8064 ~ 000000F840DF8078 范围内,这里要吐槽的是内存地址按照 大端布局 的,看起来很不习惯,可以用 windbg 用 小端布局 来显示。

0:116> dp 000000F840DF8064000000f8`40df8064  6e686f6a`00000001000d0010`00000220000000f8`40df8074  7972616d`00000002 21210000`00000220000000f8`40df8084  21212121`2121212121212121`21212121000000f8`40df8094  21212121`21212121 21212121`21212121000000f8`40df80a4  21212121`2121212121212121`21212121000000f8`40df80b4  21212121`21212121 21212121`21212121000000f8`40df80c4  21212121`2121212121212121`21212121000000f8`40df80d4  21212121`21212121 21212121`21212121

“sql 请求源码研究”

喜欢玩 windbg 的朋友肯定想对 sqlserver 进行汇编级洞察,比如研究下 sql 请求在 sqlserver 里面的执行流是什么样的?其实很简单,我们可以这样处理,使用 ba 对 john 的内存地址下一个硬件断点,即 ba r4 000000f840df8064+0x4,然后在 SSMS 上执行一条 SELECT * FROM person 语句,因为要提取 john 自然就会命中。

0:104> ba r4 000000f840df8064+0x40:104> gBreakpoint 0 hitsqlmin!BTreeMgr::GetHPageIdWithKey+0x4a:00007ff8`d4ea121a 48894c2478      mov     qword ptr [rsp+78h],rcx ss:000000f8`45278028=00000248000000250:102> k # Child-SP          RetAddr               Call Site00 000000f8`45277fb0 00007ff8`d4ea0b59     sqlmin!BTreeMgr::GetHPageIdWithKey+0x4a01000000f8`45278450 00007ff8`d4ea08b7     sqlmin!IndexPageManager::GetPageWithKey+0x11902000000f8`45278d20 00007ff8`d4eb22d1     sqlmin!GetRowForKeyValue+0x20303000000f8`45279880 00007ff8`d4eb2a39     sqlmin!IndexDataSetSession::GetRowByKeyValue+0x14104000000f8`45279a70 00007ff8`d4eb279b     sqlmin!IndexDataSetSession::FetchRowByKeyValueInternal+0x23005000000f8`45279ed0 00007ff8`d4eb2883     sqlmin!RowsetNewSS::FetchRowByKeyValueInternal+0x43706000000f8`4527a000 00007ff8`d4eaadab     sqlmin!RowsetNewSS::FetchRowByKeyValue+0x9607000000f8`4527a050 00007ff8`d4f93d60     sqlmin!CMEDScan::StartSearch+0x4f808 000000f8`4527a170 00007ff8`d4f93f3a     sqlmin!CMEDCatYukonObject::GetTemporalCurrentTableId+0x10e09000000f8`4527a380 00007ff8`d801f0d1     sqlmin!CMEDProxyRelation::GetTemporalCurrentTableId+0x7a0a000000f8`4527a3c0 00007ff8`d801dfb8     sqllang!CAlgTableMetadata::FPartialBind+0xb580b000000f8`4527a580 00007ff8`d80394b3     sqllang!CAlgTableMetadata::Bind+0x3170c000000f8`4527a620 00007ff8`d800415d     sqllang!CRelOp_Get::BindTree+0x78f0d000000f8`4527a890 00007ff8`d80418a1     sqllang!COptExpr::BindTree+0x850e000000f8`4527a8c0 00007ff8`d800415d     sqllang!CRelOp_FromList::BindTree+0x310f000000f8`4527a920 00007ff8`d802c2a3     sqllang!COptExpr::BindTree+0x8510000000f8`4527a950 00007ff8`d800415d     sqllang!CRelOp_QuerySpec::BindTree+0x2e811000000f8`4527aa60 00007ff8`d80042dd     sqllang!COptExpr::BindTree+0x8512000000f8`4527aa90 00007ff8`d800415d     sqllang!CRelOp_SelectQuery::BindTree+0x48913000000f8`4527ab80 00007ff8`d8003f23     sqllang!COptExpr::BindTree+0x8514000000f8`4527abb0 00007ff8`d8004e47     sqllang!CRelOp_Query::FAlgebrizeQuery+0x4bd15 000000f8`4527ae30 00007ff8`d7ff5576     sqllang!CProchdr::FNormQuery+0x8f16 000000f8`4527ae70 00007ff8`d7ff4a79     sqllang!CProchdr::FNormalizeStep+0x5bd17 000000f8`4527b4b0 00007ff8`d7ff5124     sqllang!CSQLSource::FCompile+0xea518000000f8`4527e1b0 00007ff8`d7e659c3     sqllang!CSQLSource::FCompWrapper+0xcb19000000f8`4527e280 00007ff8`d7e6387a     sqllang!CSQLSource::Transform+0x7211a000000f8`4527e3e0 00007ff8`d7e6e67b     sqllang!CSQLSource::Execute+0x4fa1b 000000f8`4527e8c0 00007ff8`d7e6d815     sqllang!process_request+0xca61c000000f8`4527efc0 00007ff8`d7e6d5ef     sqllang!process_commands_internal+0x4b71d000000f8`4527f0f0 00007ff8`d4096523     sqllang!process_messages+0x1d61e 000000f8`4527f2d0 00007ff8`d4096e6d     sqldk!SOS_Task::Param::Execute+0x2321f000000f8`4527f8d0 00007ff8`d4096c75     sqldk!SOS_Scheduler::RunTask+0xa520000000f8`4527f940 00007ff8`d40bb160     sqldk!SOS_Scheduler::ProcessTasks+0x39d21 000000f8`4527fa60 00007ff8`d40baa5b     sqldk!SchedulerManager::WorkerEntryPoint+0x2a122000000f8`4527fb30 00007ff8`d40bafa4     sqldk!SystemThreadDispatcher::ProcessWorker+0x3ed23 000000f8`4527fe30 00007ff8`f6d86fd4     sqldk!SchedulerManager::ThreadEntryPoint+0x3b524000000f8`4527ff20 00007ff8`f865cec1     KERNEL32!BaseThreadInitThunk+0x1425000000f8`4527ff50 00000000`00000000     ntdll!RtlUserThreadStart+0x21

从线程栈上看,有 SQLSERVER 核心的 Scheduler ,Task 以及 命令分析器,查询优化器,查询执行器 等各种核心元素,后续再慢慢研究吧。

“总结”

深入的理解数据,索引在数据页上的布局,可以从根本上帮助我们理解如何减少请求在数据页上的流转,减少逻辑读,从而提升 sql 的查询性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/508.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C++】模板初阶

文章目录泛型编程函数模板概念格式实例化匹配原则类模板定义格式实例化泛型编程 当我们的一个函数涉及到多个类型的处理时,我们就需要重载函数来实现,但是重载函数是存在一些局限性的。   重载函数仅仅是类型不同,代码的复用率较低&#xf…

【AcWing】蓝桥杯备赛-深度优先搜索-dfs(2)

目录 写在前面: 题目:94. 递归实现排列型枚举 - AcWing题库 读题: 输入格式: 输出格式: 数据范围: 输入样例: 输出样例: 解题思路: 代码: AC &…

使用new bing简易教程

申请new bing 首先先申请new bing然后等待通过,如下图 申请完,用edge浏览器,若有科学方法,就能在右上角的聊天进行向AI提问 使用插件来进行直接访问New Bing 在edge浏览器中安装一个插件,地址为:Mod…

HTML樱花飘落

樱花效果 FOR YOU GIRL 以梦为马&#xff0c;不负韶华 LOVE YOU FOREVER 实现代码 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html><head><meta http-equiv"…

Windows逆向安全(一)之基础知识(二)

反汇编分析C语言 空函数反汇编 #include "stdafx.h"//空函数 void function(){}int main(int argc, char* argv[]) {//调用空函数function();return 0; }我们通过反汇编来分析这段空函数 函数外部 12: function(); 00401048 call ILT5(func…

一款丧心病狂的API测试工具:Apifox!

你好&#xff0c;我是测试开发工程师——凡哥。欢迎和我交流测试领域相关问题&#xff08;测试入门、技术、python交流都可以&#xff09; 我们平时在做接口测试的时候&#xff0c;对于一些常用的接口测试工具的使用应该都非常熟悉了&#xff1a; 接口文档&#xff1a;Swagge…

2023年网络安全比赛--attack(新)数据包分析中职组(超详细)

一、竞赛时间 180分钟 共计3小时 任务环境说明: 1 分析attack.pcapng数据包文件,通过分析数据包attack.pcapng找出恶意用户第一次访问HTTP服务的数据包是第几号,将该号数作为Flag值提交; 2.继续查看数据包文件attack.pcapng,分析出恶意用户扫描了哪些端口,将全部的端口号…

比df更好用的命令!

大家好&#xff0c;我是良许。 对于分析磁盘使用情况&#xff0c;有两个非常好用的命令&#xff1a;du 和 df 。简单来说&#xff0c;这两个命令的作用是这样的&#xff1a; du 命令&#xff1a;它是英文单词 disk usage 的简写&#xff0c;主要用于查看文件与目录占用多少磁…

π-Day快乐:Python可视化π

π-Day快乐&#xff1a;Python可视化π 今天是3.14&#xff0c;正好是圆周率 π\piπ 的前3位&#xff0c;因此数学界将这一天定为π\bold{\pi}π day。 π\piπ 可能是最著名的无理数了&#xff0c;人类对 π\piπ 的研究从未停止。目前人类借助计算机已经计算到 π\piπ 小数…

考研408 王道计算机考研 (初试/复试) 网课笔记总结

计算机初试、复试笔记总结&#xff08;导航栏&#xff09;&#x1f4dd; 408 考研人&#xff0c;人狠话不多&#xff1a;3、2、1&#xff0c;上链接 &#xff01; 408 考研初试 - 备战期&#xff0c;专业课笔记&#xff0c;导航&#x1f6a5;&#x1f6a5;&#x1f6a5; &…

编写Java哪个编译器好

现在能够编写Java代码的工具简直不要太多&#xff0c;各种各样五花八门&#xff0c;但目前效率最高的还是Intellij Idea。但这个工具对于完全零基础的小白来说&#xff0c;第一次用起来是比较复杂的&#xff0c;因为它的功能太多了。这就好比你要学开车&#xff0c;如果上来就给…

量化(1):基础知识

1. Tops的含义 1TOPS代表处理器每秒可进行一万亿次(10^12)操作 2. 定点数 2.1 定点数的含义 大家都知道,数字既包括整数,又包括小数,如果想在计算机中,既能表示整数,也能表示小数,关键就在于这个小数点如何表示? 计算机科学家们想出一种方法,即约定计算机中小数…

MySQL:JDBC

什么是JDBC&#xff1f; JDBC( Java DataBase Connectivity ) 称为 Java数据库连接 &#xff0c;它是一种用于数据库访问的应用程序 API &#xff0c;由一组用Java语言编写的类和接口组成&#xff0c;有了JDBC就可以 用统一的语法对多种关系数据库进行访问&#xff0c;而不用担…

Docker三剑客之swarm

一、什么是docker swarm Swarm是Docker公司推出的用来管理docker集群的平台&#xff0c;几乎全部用GO语言来完成的开发的&#xff0c;代码开源在https://github.com/docker/swarm&#xff0c; 它是将一群Docker宿主机变成一个单一的虚拟主机&#xff0c;Swarm使用标准的Docker…

排序算法 - 冒泡排序

冒泡排序算法应该可以说是很经典的一种对数据进行排序的的算法了&#xff0c;甚至在很多的介绍算法的数据中&#xff0c;它可能还是放在最前面开始讲解的。 冒泡排序算法到底是咋样的呢&#xff1f;冒泡这个说法又是怎么得来的呢&#xff1f; 首先先理解一下冒泡算法的实现原理…

Java开发 - 布隆过滤器初体验

目录 前言 布隆过滤器 什么是布隆过滤器 布隆过滤器的作用 布隆过滤器原理 怎么设计布隆过滤器 布隆过滤器使用案例 安装布隆过滤器 添加依赖 添加配置 添加工具类 添加测试代码 简单测试 特别提醒​​​​​​​ 结语 前言 前面三篇&#xff0c;已经把消息队列…

裸辞3个月,面试了25家公司,终于找到心仪的工作了

​上半年裁员&#xff0c;下半年裸辞&#xff0c;有不少人高呼裸辞后躺平真的好快乐&#xff01;但也有很多人&#xff0c;裸辞后的生活五味杂陈。 面试25次终于找到心仪工作 因为工作压力大、领导PUA等各种原因&#xff0c;今年2月下旬我从一家互联网小厂裸辞&#xff0c;没…

蓝桥杯刷题第九天

题目描述本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。素数就是不能再进行等分的整数。比如7&#xff0c;11。而 9 不是素数&#xff0c;因为它可以平分为 3 等份。一般认为最小的素数是2&#xff0c;接着是 3&#xff0c;5&…

深度学习面试题汇总(一)

深度学习面试题汇总&#xff08;一&#xff09; 文章目录深度学习面试题汇总&#xff08;一&#xff09;1.Dropout1.1Dropout在训练的过程中会随机去掉神经元&#xff0c;那么在编码过程中是怎么处理的呢&#xff1f;1.2dropout的训练过程需要做rescale&#xff0c;这个过程是什…

Candence PCB Si 仿真设计篇3:板级链路仿真

接上篇Candence PCB Si 仿真设计篇2&#xff1b;提示仿真链路中无VIA过孔仿真模型&#xff0c;可手动添加VIA过孔仿真模型&#xff1b; 1.添加过孔VIA仿真模型. 在SigXplorer PCB SI GXL界面中&#xff0c;菜单栏Analyze->Via Model Generator弹出设置VIA模型设置&#xf…
最新文章