sql - Azure SQL 上的 sql 选择查询中的参数是否存在问题?
问题描述
我正在尝试查找 Azure SQL 上此选择查询的问题所在。它运行大约 700 毫秒。
DECLARE @LanguageIds1 INT = 11;
DECLARE @LanguageIds2 INT = 14;
SELECT
[G].[Id],
[G].[Name],
COUNT(*) AS [AudiobookCount]
FROM [Genre] AS [G]
INNER JOIN [Audiobook2Genre] AS [A2G] ON [A2G].[GenreId] = [G].[Id]
INNER JOIN [Audiobook] AS [A] ON [A].[Id] = [A2G].[AudiobookId]
WHERE [A].[LanguageId] IN (@LanguageIds1,@LanguageIds2)
GROUP BY [G].[Id], [G].[Name]
ORDER BY [G].[Name]
当我将其更改为此(删除参数并直接放置值)。
SELECT
[G].[Id],
[G].[Name],
COUNT(*) AS [AudiobookCount]
FROM [Genre] AS [G]
INNER JOIN [Audiobook2Genre] AS [A2G] ON [A2G].[GenreId] = [G].[Id]
INNER JOIN [Audiobook] AS [A] ON [A].[Id] = [A2G].[AudiobookId]
WHERE [A].[LanguageId] IN (11,14)
GROUP BY [G].[Id], [G].[Name]
ORDER BY [G].[Name]
它只运行大约 80 毫秒。所以运行时间的差异大约是 620 毫秒,我不明白为什么。
我尝试通过 bacpac 将数据库从 Azure 复制到本地 MSSQL 2017 Developer Edition 并运行相同的查询。运行时间大致相同。
解决方案
原因是 SQL Server 并不总是为您的查询选择最佳执行计划,幸运的是,有几种不同的提示可用于强制 SQL Server 使用一个执行计划而不是另一个。您可能会遇到的一个问题是,在 WHERE 子句中使用参数时,有时查询运行良好,有时运行速度非常慢。
如上所述,SQL Server 提供了许多提示,可用于强制执行计划如何组合在一起。我们感兴趣的选项是 OPTIMIZE FOR 选项。这将允许我们指定我们希望 SQL Server 在创建执行计划时使用的参数值。
请参考本教程:Optimize Parameter Driven Queries with SQL Server OPTIMIZE FOR Hint。
也许您可以像这样修改代码并再次测试。
DECLARE @LanguageIds1 INT = 11;
DECLARE @LanguageIds2 INT = 14;
SELECT
[G].[Id],
[G].[Name],
COUNT(*) AS [AudiobookCount]
FROM [Genre] AS [G]
INNER JOIN [Audiobook2Genre] AS [A2G] ON [A2G].[GenreId] = [G].[Id]
INNER JOIN [Audiobook] AS [A] ON [A].[Id] = [A2G].[AudiobookId]
WHERE [A].[LanguageId] IN (@LanguageIds1,@LanguageIds2)
GROUP BY [G].[Id], [G].[Name]
ORDER BY [G].[Name]
OPTION (OPTIMIZE FOR (@LanguageIds1= 11,@LanguageIds2= 14))
有关更多详细信息:您可以查看提示 (Transact-SQL) - 查询。
您也可以参考这个案例:为什么参数化查询产生的查询计划与非参数化查询相比要慢得多。
希望这可以帮助。
推荐阅读
- mysql - 2个关系之间可以有关系(数据库)吗?
- node.js - Nodejs Sequelize sqlite3 没有这样的表
- angular - 从 Ionic 3 升级到 5 - .map 不再适用于可观察对象
- javascript - 如何在数组之间使用过滤器获取数据?
- python - 使用不和谐的频道历史记录时没有昵称属性
- google-cloud-pubsub - 为 Google PubSub 暂停 Spring Cloud StreamListener
- python - 如何计算选定范围的平均值?(熊猫)
- vue.js - 使用 vee-validate 在插槽中丢失反应性
- javascript - 在文本校正时,触发事件。可能的?
- python - 我正在使用 django 1.11.9 这个语句“关于页面”不会被渲染有什么问题