首页 > 解决方案 > 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 并运行相同的查询。运行时间大致相同。

标签: sqlsql-serverazure

解决方案


原因是 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) - 查询

您也可以参考这个案例:为什么参数化查询产生的查询计划与非参数化查询相比要慢得多。

希望这可以帮助。


推荐阅读