簡體   English   中英

如何使用索引加速當前查詢

[英]How to speed up current query with index

我在Azure SQL數據庫中使用v12服務器,我有下表:

CREATE TABLE [dbo].[AudienceNiches]( [Id] [bigint] IDENTITY(1,1) NOT NULL, [WebsiteId] [nvarchar](128) NOT NULL, [VisitorId] [nvarchar](128) NOT NULL, [VisitDate] [datetime] NOT NULL, [Interest] [nvarchar](50) NULL, [Gender] [float] NULL, [AgeFrom18To24] [float] NULL, [AgeFrom25To34] [float] NULL, [AgeFrom45To54] [float] NULL, [AgeFrom55To64] [float] NULL, [AgeFrom65Plus] [float] NULL, [AgeFrom35To44] [float] NULL, CONSTRAINT [PK_AudienceNiches] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) )

我正在執行此查詢:(更新查詢)

`select  a.interest, count(interest) from (
select visitorid, interest
from audienceNiches
WHERE WebsiteId = @websiteid
AND VisitDate >= @startdate
AND VisitDate <= @enddate
group by visitorid, interest) as a
group by a.interest`

我有以下索引(所有ASC):

idx_WebsiteId_VisitDate_VisitorId idx_WebsiteId_VisitDate idx_VisitorId idx_Interest

問題是我的查詢返回18K行aproximaly並需要5秒,整個表有8.8M記錄,如果我擴展一點數據時間增加了很多,那么,這個查詢的最佳索引是什么? 我錯過了什么?

在沒有要測試的數據的情況下編寫SQL很困難,但看看這是否能夠以更好的執行時間提供您正在尋找的結果。

SELECT interest, count(distinct visitorid)
FROM audienceNiches
WHERE WebsiteId = @websiteid
AND VisitDate between @startdate and @enddate
AND interest is not null 
GROUP BY interest

此查詢的最佳索引是這些列的復合索引,順序如下:

  • WebsiteId
  • VisitDate
  • 利益
  • VisitorId

這允許從索引完全回答查詢。 SqlServer可以掃描范圍( WebsiteIdVisitDate ),然后排除null Interest ,最后從索引中計算不同的VisitorIds 索引條目的順序正確,以便有效地執行這些操作。

索引可能需要幾乎無限的理解,但在您的情況下,我認為通過將WebsiteId和VisitDate索引為單獨的索引,您會看到良好的性能提升。

盡管確保您的索引處於良好狀態非常重要。 您需要通過保持最新的統計信息並定期重建索引來維護它們。

最后,您應該在調整查詢性能時檢查查詢計划。 SQL Server會告訴您它是否認為它會從索引的一列(或多列)中受益,並且還會提醒您其他與性能相關的問題。

在Management Studio中按Ctrl + L,查看查詢的內容。

您的查詢可以用這種方式編寫,因為在最終結果集中,您不會從表audienceNiches中提取列visitorid,因此無需編寫兩個不同級別的group by。 請查看此查詢,並告知我是否仍然面臨性能問題。

select  interest, count(interest)
from audienceNiches
WHERE WebsiteId = @websiteid
AND VisitDate >= @startdate
AND VisitDate <= @enddate
group by interest

首先,您的更新查詢可以有效地減少到:

select an.Interest, count(an.Interest)
from dbo.AudienceNiches an
where an.WebsiteId = @WebSiteId
    and an.VisitDate between @startdate and @enddate
group by an.Interest;

其次,根據數據的基數,以下索引之一將提供最佳性能:

create index IX_AudienceNiches_WebSiteId_VisitDate_Interest on dbo.AudienceNiches
(WebSiteId, VisitDate, Interest);

要么

create index IX_AudienceNiches_VisitDate_WebSiteId_Interest on dbo.AudienceNiches
(VisitDate, WebSiteId, Interest);

然而,隨着您的數據增長,我認為最終后者平均會變得更有效率。

PS你的表在多個方面嚴重非規范化。 我只希望你知道你在做什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM