使用SQL Server 2008/2012,我目前有两个表,如下所示:
tblAccount (accountID BIGINT, accountActive BIT)
tblSite (siteID BIGINT, accountID BIGINT, siteActive BIT)
目前,accountID
上的tblAccount
是主键和聚集索引。
siteID
上的tblSite
是主键和聚集索引
我的大部分查询都采用以下形式:
SELECT <fields>
FROM <some table> X
INNER JOIN tblSite s ON s.siteID = X.siteID
INNER JOIN tblAccount a ON a.accountID = s.accountID
WHERE
x.<field> = SOMETHING
AND a.accountActive = 1
AND s.siteActive = 1
我的理解是,为了优化这些查询,最好将新的聚簇索引放在tblAccount
和tblSite
上。
类似的东西:
CREATE CLUSTERED INDEX ON tblAccount (accountActive,accountID) WITH .....
CREATE CLUSTERED INDEX ON tblSite (siteActive,siteID) WITH .....
显然,要做到这一点,我必须删除两个表的PK聚簇索引。
这是否有可能导致问题进一步发生?正如我假设(采用帐户表),该表现在已针对
进行了优化SELECT *
FROM tblAccount
WHERE accountID = X
AND accountActive = Y
所以只做
SELECT *
FROM tblAccount
WHERE accountID = X
将是高度未经优化的吗?
我在帐户表上创建了另外两个索引,我不知道这些索引会对上述索引产生多大影响。查询:
CREATE UNIQUE NONCLUSTERED INDEX idx_account_session
ON tblAccount (accountSessionKey,accountActive,accountAffirmed,accountLastAction)
INCLUDE (accountID)
WITH (STATISTICS_NORECOMPUTE=OFF,SORT_IN_TEMPDB=ON,FILLFACTOR=80)
CREATE NONCLUSTERED INDEX idx_account_login
ON tblAccount (accountEmail,accountPassword,accountAffirmed,accountActive)
INCLUDE (accountID,accountSaltHash)
WITH (STATISTICS_NORECOMPUTE=OFF,SORT_IN_TEMPDB=ON,FILLFACTOR=80)
我已经将这些用于优化身份验证存储过程。
非常感谢你的帮助。
答案 0 :(得分:1)
更改聚簇索引将改变表的工作方式,当前accountID
是唯一的,但如果您在accountID和Active上创建聚簇索引,则最终可能会有2条记录用于同一帐户ID(一个活动,一个不)。因此,为了更改聚类键并保持AccountID唯一,您还需要添加唯一约束(或唯一索引)。
如果您将在大多数时间查询活动帐户/网站,并且您认为性能有问题,我会选择indexed view,并将您的聚集索引保持在accountID上。< / p>
CREATE VIEW dbo.ActiveAccount
WITH SCHEMABINDING
AS
SELECT AccountID, <Columns>
FROM dbo.tblAccount
WHERE ActiveAccount = 1;
GO
CREATE UNIQUE CLUSTERED INDEX UQ_ActiveAccount_AccountID
ON dbo.ActiveAccount (AccountID);
GO
还有类似的Site索引视图,因此您的查询变为:
SELECT <columns>
FROM ActiveAccount A (NOEXPAND)
INNER JOIN ActiveSite s (NOEXPAND)
ON a.accountID = s.accountID;
但是当您希望所有帐户/网站不仅仅是活动帐户/网站时,您可以查询主表而不是索引视图。
请注意,维护此索引视图的成本可能超过您从中获取的好处,如评论中所述,它取决于数据的基数,以及您只需要查询活动帐户/网站。