.net - 如何练习大型 SQL Server 索引或分区问题进行面试?
问题描述
对不起,如果这应该是关于职业或工作场所堆栈交换的。它似乎跨越了界限,所以我不知道该放哪一个。
我即将在一家非常理想的公司进行现场技术面试,但这超出了我目前的技能范围。我是高级 Java 人。这个机会不仅跨越到 .NET 堆栈,而且在一个团队中,他们正在对大型 SQL Server 数据库(可能是数十亿行?)进行多线程查询。
有一次,经理说,“我不想浪费你的时间,但如果你愿意,我可以带你进来……”我很惊讶他没有简单地说,对不起,你没有我们需要的技能。我完全脱离了我的元素。在我的职业生涯中,我做过各种数量和深度的 SQL,但没有达到这个规模,而且最近也没有(最近做了更多的 noSQL,比如 Mongo 和 Amazon Dynamo)。但我正在经历它,因为我正在这个地方寻找任何人(并且讨厌目前的工作,并且有时间准备)。
我已经完成了 SQL Server 技术面试问题之类的基本搜索,并且已经开始研究它们,但这并不能代替实际经验。有没有办法用一些大的公共数据来设置我自己的大型 SQL Server 来练习其中的一些?
解决方案
我只是想表明我将从哪里开始。
创建没有 VARCHAR(MAX) 的表以避免性能问题
CREATE TABLE Person ( PersonID INT NOT NULL, FirstName VARCHAR(50), LastName VARCHAR(50), Address VARCHAR(50) )
插入一些测试数据。该表在加载数据之前不应有任何索引,因为索引会降低插入性能
DECLARE @RunDate datetime SET @RunDate=GETDATE() DECLARE @values TABLE (DataValue int, RandValue INT) ;WITH mycte AS ( SELECT 1 DataValue UNION all SELECT DataValue + 1 FROM mycte WHERE DataValue + 1 <= 1000000 ) INSERT INTO Person(PersonID, FirstName, LastName, Address) SELECT DataValue , 'FirstName' + CAST(DataValue AS VARCHAR(10)) , 'LastName' + CAST(DataValue AS VARCHAR(10)) , 'Address' + CAST(DataValue AS VARCHAR(10)) FROM mycte m OPTION (MAXRECURSION 0)
然后创建索引。
-- Clustered index ALTER TABLE dbo.Person ADD CONSTRAINT PK_PersonID PRIMARY KEY CLUSTERED (PersonID); CREATE NONCLUSTERED INDEX [IX_Person_FirstName_LastName] ON dbo.Person (FirstName, LastName) INCLUDE(Address)
练习查询调优。点击
Ctrl + M
SSMS 查看查询计划。比较查询计划。尝试调整查询Query 2
:-- Query 1 SELECT * FROM dbo.Person p WHERE p.FirstName = 'FirstName1' -- Query 2 SELECT * FROM dbo.Person p WHERE p.Address = 'Address1'
当您进行 I/O 操作时,您应该使用异步操作。所以你需要使用一些ORM。例如,实体框架 在我的经验中,当您使用 IO 时,我还没有找到在 ASP.NET MVC 中使用多线程的理由,因为所有逻辑都在数据库中执行。所以 SQL Server 的优化器自己进行并行化。因此在处理 IO 操作时无需使用多线程。
public async Task<List<Person>> GetAllPersonsWithName(string personName) { return await db.Persons.Where(u => u.FirstName == personName).ToListAsync(); }
然后尝试异步运行存储过程(如果您使用异步操作,您的团队会很高兴)
Task<int> firstResult = db.Database.ExecuteSqlCommandAsync("exec FooProcedure @param", new SqlParameter("@param", yourParam)); Task<int> secondResult = db.Database.ExecuteSqlCommandAsync("exec FooProcedure1 @param1", new SqlParameter("@param1", yourParam1)); await Task.WhenAll(mcResult, dcaiResult); int fr = firstResult.Result; int sr = secondResult.Result; Console.WriteLine($"Results are fr {fr}, sr {sr} ");
C#
当您编写和T-SQL
编码时,还有一些建议:
C# 代码必须是
async
. 作为async/await
保存线程。高性能和可扩展性不能与每个套接字一个线程一起使用。好文章值得阅读。这段代码真的很酷!此外,如果您未来的团队使用 EntityFramework,则在选择数据时使用方法,而不是添加或更新:
.AsNoTracking()
context.YourTable.AsNoTracking()
尽量避免编写复杂的
LINQ to Entities
查询。AsEntityFramework
可以创建类型为 like 的变量VARCHAR(MAX)
。这会降低性能。相反,只需创建用户定义的函数。对于复杂的逻辑使用stored procedures
,views
,user-defined functions
.尝试调整查询。阅读这篇关于查询调优的文章。另外,做个测试例子,尝试实现index seek操作,找到解决key lookups的方法(避免任何
implicit\explicit conversions
inWHERE
语句,在index或者include
这个列中添加列)。可以在AdventureWorks
数据库中进行调整查询。
推荐阅读
- mysql - 我该如何解决这个不正确的数据?
- html - 我正在使用 Ajax 在页面上显示 html。我希望添加的 css 不会影响整个页面
- reactjs - MUI Paper 覆盖 MUI 警报背景
- r - 为什么 gtools::combinations 和 permutations 不适用于包含相同元素的向量?
- php - 使用默认的 Woocommerce 单一产品页面覆盖变体描述
- imagemagick - Redmine 4.2.3 和 FreeBSD 13.0 上的 MiniMagick::Error(您必须安装 ImageMagick 或 GraphicsMagick)
- java - 为什么会发生 PoolingException?
- node.js - 如何通过 Postman 发送嵌套数组
- php - 字母数字正则表达式不适用于非罗马字符
- c - Linux信号父子[c]