如果您缺少信息,我可以在请求时附加它们。
工作区
我有一个运行在MS SQL 2012标准版上的数据库,其结构如下:
表: 1.用户(id、softId(非唯一)、出生日期) - 行数:1050万 - 索引:三列和出生日期(聚集索引) 2.文档(docId、userId、创建日期、删除日期、姓氏、名字、分类ID) - 行数:2300万 - 索引:姓氏、名字、docId、创建日期、userID(聚集索引) - 注意:在这种情况下,名称与文档相关,而不是与userId相关。 3.分类(id、描述) - 行数:200 4.三个“数据”表 - 行数:100万、130万和30万 - 索引:docIds
关系: - 用户到文档:1对n - 分类到文档:1对n - 文档到数据表:1对n
为了选择完整的记录,我目前使用以下语句:
服务器执行时间为16秒。
工作区
我有一个运行在MS SQL 2012标准版上的数据库,其结构如下:
表: 1.用户(id、softId(非唯一)、出生日期) - 行数:1050万 - 索引:三列和出生日期(聚集索引) 2.文档(docId、userId、创建日期、删除日期、姓氏、名字、分类ID) - 行数:2300万 - 索引:姓氏、名字、docId、创建日期、userID(聚集索引) - 注意:在这种情况下,名称与文档相关,而不是与userId相关。 3.分类(id、描述) - 行数:200 4.三个“数据”表 - 行数:100万、130万和30万 - 索引:docIds
关系: - 用户到文档:1对n - 分类到文档:1对n - 文档到数据表:1对n
为了选择完整的记录,我目前使用以下语句:
服务器执行时间为16秒。
SELECT * FROM (
select * from docs
where userID in (
select distinct userID from users where softId like '...'
)
) as doc
LEFT JOIN users on users.userID = doc.userId
LEFT JOIN classifications on classifications.id = doc.classificationId
LEFT JOIN data1 on data1.docId = doc.docId
LEFT JOIN data2 on data2.docId = doc.docId
LEFT JOIN data3 on data3.docId = doc.docId;
更新 - 现在为15秒
SELECT
docID, calssificationId, classificationDescription,
userId, softId, forename, lastname, birthdate,
data1.id, data1.date, data2.id, data2.date, data3.id, data3.date,
FROM docs
JOIN users on users.userID = doc.userId AND softId like '...'
LEFT JOIN classifications on classifications.id = doc.classificationId
LEFT JOIN data1 on data1.docId = doc.docId
LEFT JOIN data2 on data2.docId = doc.docId
LEFT JOIN data3 on data3.docId = doc.docId;
执行计划
服务器执行时间为17秒
DECLARE @userIDs table( id bigint );
DECLARE @docIDs table( id bigint );
insert into @userIDs select userID from users where softId like '...';
insert into @docIDs select docId from docs where userId in ( select id from @userIDs);
SELECT * FROM users where userID in ( select id from @userIDs);
SELECT * FROM docs where docID in (select id from @docIDs);
SELECT * FROM data1 where data1.docId in (select id from @docIDs);
SELECT * FROM data2 where data2.docId in (select id from @docIDs);
SELECT * FROM data3 where data3.docId in (select id from @docIDs);
GO
更新 - 现在为14秒
DECLARE @userIDs table( id bigint, softId varchar(12), birthdate varchar(8) );
DECLARE @docIDs table( id bigint, classification bigint, capture_date datetime, userId bigint, lastname varchar(50), forename varchar(50) );
INSERT INTO @userIDs select userID, softId, birthdate from users where softId like '...';
INSERT INTO @docIDs select docID, classification, capture_date, userID, lastname, forename from docs where userID in ( select id from @userIDs);
SELECT * FROM @userIDs;
SELECT * FROM @docIDs;
SELECT [only needed fields] FROM data1 where docID in (select id from @docIDs);
SELECT [only needed fields] FROM data2 where docID in (select id from @docIDs);
SELECT [only needed fields] FROM data3 where docID in (select id from @docIDs);
执行计划
常规更新 @AntonínLejsek建议将文档的docId作为聚集索引,将pkId作为非聚集索引。这改变了执行时间如下:
- Join语句:-1秒
- Multi-Select语句:-5秒
我再次检查了索引并更改了包含的列,现在它们的执行时间是:
- Join语句:4秒
- Multi-Select语句:6秒
“简单”的问题
是否有人有减少执行时间的建议?
select *
合适吗,还是只需要检索特定的字段?能否发布执行计划? - alroc