【发布时间】:2011-07-27 21:29:03
【问题描述】:
这是一个依赖于两个非聚集索引的基本查询:
SELECT cc.categoryid, count(*) from company c
INNER JOIN companycategory cc on cc.companyid = c.id
WHERE c.placeid like 'ca_%'
GROUP BY cc.categoryid order by count(*) desc
当完全相同的数据库托管在 SQL Server 2008 上时,几乎在任何硬件上,这都会返回
DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS
...在传统 SQL 上,这仍然会在大约 1 秒内返回。
在 Azure 上,每次返回大约需要 3.5 秒。
一些articles 似乎表明人们普遍对SQL Azure 中的查询性能感到满意。然而,这是一个基本场景,其中“明显”的调整已经用尽,并且没有网络延迟问题可言。在处理大型表时,它真的很慢(companycategroy 有 120 万条记录,places 有 7.5K)。
数据库总大小不超过 4GB。选择“Web”版本与“Enterprise”版本似乎也没有太大区别。
我错过了什么?
这只是一个基本示例,只有更复杂的查询会变得更糟,所有查询都经过 reviewed 调整,并且在本地运行良好。
这是执行计划:
|--Sort(ORDER BY:([Expr1004] DESC))
|--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(int,[Expr1007],0)))
|--Hash Match(Aggregate, HASH:([cc].[CategoryId]), RESIDUAL:([XX].[dbo].[CompanyCategory].[CategoryId] as [cc].[CategoryId] = [XX].[dbo].[CompanyCategory].[CategoryId] as [cc].[CategoryId]) DEFINE:([Expr1007]=COUNT(*)))
|--Hash Match(Inner Join, HASH:([c].[Id])=([cc].[CompanyId]))
|--Index Scan(OBJECT:([XX].[dbo].[Company].[IX_Company_PlaceId] AS [c]), WHERE:([XX].[dbo].[Company].[PlaceId] as [c].[PlaceId] like N'ca_%'))
|--Index Scan(OBJECT:([XX].[dbo].[CompanyCategory].[IX_CompanyCategory_CompanyId] AS [cc]))
以下是统计数据:
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time:
CPU time = 14 ms, elapsed time = 14 ms.
(789 row(s) affected)
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'CompanyCategory'. Scan count 1, logical reads 5183, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Company'. Scan count 1, logical reads 8710, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 3328 ms, elapsed time = 3299 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
索引定义如下:
CREATE NONCLUSTERED INDEX [IX_Company_PlaceId] ON [dbo].[Company]
(
[PlaceId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
CREATE NONCLUSTERED INDEX [IX_CompanyCategory_CompanyId] ON [dbo].[CompanyCategory]
(
[CompanyId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
ALTER TABLE [dbo].[Company] ADD CONSTRAINT [PK_Company_Id] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
【问题讨论】:
-
能否在
Azure上发布查询的文本查询计划和统计信息?请运行SET STATISTICS IO ON SET STATISTICS TIME ON GO SET SHOWPLAN_TEXT ON GO SELECT … -
我们当然可以查看查询计划...
-
我们在 Azure 上有执行计划。我们应该看到他的本地数据库运行速度如此之快。
-
@todda.speot.is,我相信 Azure 默认具有自动统计功能。 Company.Id 是一个整数(代理键),Place.Id 是一个 varchar(50) 自然键。
-
@Steve:我们在这里看不到集群搜索。如果
id是聚集的PK,则它会被任何其他索引隐式包含。
标签: sql-server azure azure-sql-database