【发布时间】:2015-07-20 14:16:00
【问题描述】:
考虑以下示例:
SET NOCOUNT ON;
CREATE TABLE #Users
(
ID INT IDENTITY(1,1),
Name VARCHAR(50)
);
CREATE CLUSTERED INDEX IDX_C_Users_UserID ON #Users(ID);
-- CREATE INDEX IDX_Users_Name ON #Users(Name); -- It doesn't work.
CREATE TABLE #Towns
(
ID INT IDENTITY(1,1),
Name VARCHAR(50)
);
CREATE CLUSTERED INDEX IDX_C_Towns_UserID ON #Towns(ID)
CREATE TABLE #BeenHere
(
ID INT IDENTITY(1,1), -- for some business reason we can't use clustered index on them
UserID INT,
TownID INT
);
CREATE UNIQUE INDEX IDX_BEEN_THERE ON #BeenHere(TownID, UserID);
INSERT INTO #Towns
SELECT Prefix+Suffix FROM (
SELECT Prefix, Suffix FROM
(SELECT 'China' UNION ALL
SELECT 'Ham' UNION ALL
SELECT 'Chicken' UNION ALL
SELECT 'Great' UNION ALL
SELECT 'Loud'
) as A(Prefix)
CROSS JOIN
(SELECT 'town' UNION ALL
SELECT 'water' UNION ALL
SELECT ' City' UNION ALL
SELECT 'burg' UNION ALL
SELECT 'berg') AS B(Suffix)
) Q
ORDER BY NEWID()
;
INSERT INTO #Users(Name)
SELECT Name + ' ' + Surname FROM (
SELECT Name, Surname FROM
(SELECT 'John' UNION ALL
SELECT 'Mary' UNION ALL
SELECT 'Ann' UNION ALL
SELECT 'Salomon' UNION ALL
SELECT 'Lisa' UNION ALL
SELECT 'Patricia' UNION ALL
SELECT 'David' UNION ALL
SELECT 'Patrick' UNION ALL
SELECT 'John' UNION ALL
SELECT 'Harry' UNION ALL
SELECT 'Richard' UNION ALL
SELECT 'George'
) as A(Name)
CROSS JOIN
(SELECT 'Smith' UNION ALL
SELECT 'Kowalski' UNION ALL
SELECT 'Bush' UNION ALL
SELECT 'Truman' UNION ALL
SELECT 'Clinton' UNION ALL
SELECT 'Reagan' UNION ALL
SELECT 'Lincoln' UNION ALL
SELECT 'Goldberg' UNION ALL
SELECT 'Adams' UNION ALL
SELECT 'Wilson' UNION ALL
SELECT 'Carter') as B(Surname)
) P
ORDER BY NEWID();
INSERT INTO #BeenHere(UserID, TownID)
SELECT
TOP 10 PERCENT
#Users.ID,
#Towns.ID
FROM
#Users
CROSS JOIN
#Towns
ORDER BY NEWID();
SET NOCOUNT OFF;
SELECT
Towns.Name,
(SELECT Users.ID, Users.Name FROM #Users Users INNER JOIN #BeenHere BH ON Users.ID = BH.UserID WHERE BH.TownID = Towns.ID ORDER BY Users.Name FOR XML PATH('User'), ROOT('Users'), TYPE) as BeenThere
FROM #Towns Towns
ORDER BY Towns.Name;
DROP TABLE #BeenHere;
DROP TABLE #Users;
DROP TABLE #Towns;
正如我们在执行计划中看到的,对用户进行排序花费了上次查询所消耗资源的 78%。
是否可以在这些表上放置一些索引以提高排序性能?我不能向数据库引入向后不兼容的更改,例如在 #BeenHere(UserID, TownID) 上提供聚集索引。
【问题讨论】:
-
不,我们在执行计划中看不到任何内容,因为您没有包含它。
-
提醒一下,计划中的百分比只是估计值
-
在第一次创建索引时,您已经用 ; 关闭了它。为什么甚至在#BeenHere 中有 ID INT IDENTITY。为什么要在插入时使用 newID 排序来分割索引?
-
" 为什么在#BeenHere 中甚至有 ID INT IDENTITY" -> 因为我正在处理的旧数据库使用这种毫无意义的约定。 “为什么要在插入时使用 newID 排序来分割索引”-> 因为它更好地模拟了我必须处理的真实数据。
-
使用 CI 可以做的任何事情都可以用 NCI 做。只需包括所有必需的列。然后你得到几乎相同的物理数据结构。s
标签: sql-server tsql sqlperformance sql-optimization