GitHub Copilot 可以帮助开发人员,尤其是那些没有深入 T-SQL 专业知识的开发人员,在不需要master
数据库内部结构知识的情况下优化查询和分析性能瓶颈。 它可以分解复杂的 SQL,解释执行计划,并建议索引策略或重构机会,使开发人员能够保持其应用正常运行和性能,同时专注于功能交付。
开始吧
确保已连接到数据库,并使用 MSSQL 扩展打开活动编辑器窗口。 通过此连接, @mssql
聊天参与者可以了解数据库环境的上下文,从而提供准确的上下文感知建议。 如果没有数据库连接,聊天参与者将没有架构或数据上下文来提供有意义的响应。
以下示例使用 AdventureWorksLT2022
示例数据库,可以从 Microsoft SQL Server 示例和社区项目 主页下载该数据库。
为了获得最佳结果,请调整表和架构名称以匹配自己的环境。
确保聊天包含 @mssql
前缀。 例如,键入 @mssql
后跟问题或提示。 这可确保聊天参与者了解你请求与 SQL 相关的帮助。
使用 GitHub Copilot 优化性能
GitHub Copilot 提供了多种方法,可帮助开发人员编写高性能、生产就绪的数据库代码,而无需深入了解查询优化或执行计划分析的专业知识。 无论是生成新功能还是调查性能问题,GitHub Copilot 都可以显示见解、建议优化并帮助重构查询,所有这些作都在 Visual Studio Code 中的现有工作流中。
下面是通过聊天参与者可以询问的常见用例和示例。
优化查询
使用 GitHub Copilot 识别 SQL 或 ORM 查询中的效率低下,并建议提高性能的方法。 从重写慢查询到推荐索引或避免使用笛卡尔联接等反模式,GitHub Copilot 有助于基于当前上下文应用 T-SQL 和 ORM 最佳做法。
- 优化以下查询:
SELECT *
FROM SalesLT.SalesOrderHeader
WHERE OrderDate > '2023-01-01';
- 建议对此查询进行索引改进:
SELECT ProductID
FROM SalesLT.SalesOrderDetail
WHERE Quantity > 100;
- 重写此查询以避免笛卡尔联接。 确保新查询遵循 T-SQL 最佳做法:
SELECT * FROM Customers, Order;
- 重写此
Prisma
查询以避免不必要的嵌套选择并提高可读性:
const orders = await prisma.salesOrderHeader.findMany({
where: {
orderDate: {
gt: new Date('2023-01-01')
}
}
});
执行计划分析
执行计划提供 SQL 引擎如何处理查询的详细细分。 GitHub Copilot 可以帮助你解释执行计划,识别嵌套循环联接等瓶颈,并根据实际查询模式和索引策略建议改进。
可以使用以下查询作为示例,使用 MSSQL 扩展中的“估计/实际计划”选项生成执行计划:
SELECT soh1.SalesOrderID AS OrderA,
soh2.SalesOrderID AS OrderB,
soh1.TotalDue AS TotalA,
soh2.TotalDue AS TotalB
FROM SalesLT.SalesOrderHeader AS soh1
CROSS JOIN SalesLT.SalesOrderHeader AS soh2
WHERE soh1.TotalDue < soh2.TotalDue
ORDER BY soh2.TotalDue DESC;
- 根据数据库专家共享的执行计划,以下查询使用嵌套循环联接,这会影响应用的性能。 你能用简单的术语来解释为什么会发生这种情况? 此外,建议优化策略,以提高查询的性能。
可以使用以下查询作为示例,使用 MSSQL 扩展中的“估计/实际计划”选项生成执行计划:
SELECT c1.CustomerID,
c1.LastName,
c2.CustomerID AS MatchingCustomerID,
c2.LastName AS MatchingLastName
FROM SalesLT.Customer AS c1
INNER JOIN SalesLT.Customer AS c2
ON c1.LastName = c2.LastName
AND c1.CustomerID <> c2.CustomerID
OPTION (LOOP JOIN);
- 说明此查询的执行计划,该查询对 TotalDue 执行带有筛选器的联接:
SELECT c.CustomerID,
c.FirstName,
c.LastName,
soh.SalesOrderID,
soh.TotalDue
FROM SalesLT.Customer AS c
INNER JOIN SalesLT.SalesOrderHeader AS soh
ON c.CustomerID = soh.CustomerID
WHERE soh.TotalDue > 500;
查询重组
使用通用表表达式(CTE)重组查询可以提高可读性和可维护性,尤其是对于复杂的逻辑或嵌套子查询。 GitHub Copilot 可帮助重写现有查询以使用 CTE,同时保留意向并提高清晰度。
- 使用通用表表达式(
CTEs
)重写此查询以提高清晰度:
SELECT *
FROM (SELECT ProductID,
SUM(Quantity) AS TotalQuantity
FROM Sales
GROUP BY ProductID) AS SubQuery;
- 使用 CTE(通用表表达式)重写以下查询以提高可读性和可维护性:
SELECT soh.CustomerID,
COUNT(*) AS OrderCount
FROM SalesLT.SalesOrderHeader AS soh
WHERE soh.OrderDate > '2022-01-01'
GROUP BY soh.CustomerID
HAVING COUNT(*) > 5;
- 使用 CTE 将此查询中的聚合逻辑与筛选器条件分开:
SELECT ProductID,
AVG(UnitPrice) AS AvgPrice
FROM SalesLT.SalesOrderDetail
GROUP BY ProductID
HAVING AVG(UnitPrice) > 50;
Code-First 性能场景
使用实体框架、Prisma 或 Sequelize 等 ORM 时,如果未优化查询,性能可能会降低。 GitHub Copilot 可帮助检测和解决代码优先工作流中缺少索引、低效筛选和 N+1 问题等问题。
- 在 Prisma 项目中,如何确保在
SalesOrderHeader
中过滤OrderDate
的查询能够有效利用索引? - 使用 Entity Framework Core,如何分析和优化按订单总值检索前 10 个客户的 LINQ 查询?
- 在 Sequelize 中,如何重构查询,以提取订单历史记录以及产品详细信息以最大程度地减少 N+1 查询问题?
反馈:查询优化器助手
为了帮助我们优化和改进 MSSQL 扩展的 GitHub Copilot,请使用以下 GitHub 问题模板提交反馈: GitHub Copilot 反馈
提交反馈时,请考虑包括:
- 测试方案 - 告诉我们你关注哪些领域,例如架构创建、查询生成、安全性、本地化。
- 效果良好 - 描述任何感觉流畅、有用或超出预期的体验。
- 问题或漏洞 – 包括任何问题、不一致或令人困惑的行为。 屏幕截图或屏幕录制特别有用!
- 改进建议 - 分享改进可用性、扩大覆盖范围或增强 GitHub Copilot 响应的想法。