我从一张约有3.5亿条记录的表中选择结果,并且运行速度非常慢 - 大约10分钟。罪魁祸首似乎是 ORDER BY ,就像我删除它一样,查询只需要一点时间。这是要点:
SELECT TOP 100
(columns snipped)
FROM (
SELECT
CASE WHEN (e2.ID IS NULL) THEN
CAST(0 AS BIT) ELSE CAST(1 AS BIT) END AS RecordExists,
(columns snipped)
FROM dbo.Files AS e1
LEFT OUTER JOIN dbo.Records AS e2 ON e1.FID = e2.FID
) AS p1
ORDER BY p1.RecordExists
基本上,我按照 Files 是否有相应的记录来排序结果,因为那些不需要先处理。我可以使用 WHERE 子句运行两个查询,但如果可能的话,我宁愿在单个查询中执行此操作。
有什么方法可以加快速度吗?
答案 0 :(得分:2)
尝试使用此表单
SELECT TOP(100) *
FROM (
SELECT TOP(100)
0 AS RecordExists
--,(columns snipped)
FROM dbo.Files AS e1
WHERE NOT EXISTS (SELECT * FROM dbo.Records e2 WHERE e1.FID = e2.FID)
ORDER BY SecondaryOrderColumn
) X
UNION ALL
SELECT * FROM (
SELECT TOP(100)
1 AS RecordExists
--,(columns snipped)
FROM dbo.Files AS e1
INNER JOIN dbo.Records AS e2 ON e1.FID = e2.FID
ORDER BY SecondaryOrderColumn
) X
ORDER BY SecondaryOrderColumn
关键指标:
记录(FID)
文件(FID,SecondaryOrdercolumn)
答案 1 :(得分:1)
它之所以慢得多是因为它没有order by子句,实际上是一个非常不同的查询。
使用order by子句: 查找整个3.5亿行中的所有匹配记录。然后对它们进行排序。
没有order by子句: 找到前100个匹配的记录。停止。
答案 2 :(得分:0)
在SQL Server中,null
值的整理低于域中的任何值。鉴于这两个表:
create table dbo.foo
(
id int not null identity(1,1) primary key clustered ,
name varchar(32) not null unique nonclustered ,
)
insert dbo.foo ( name ) values ( 'alpha' )
insert dbo.foo ( name ) values ( 'bravo' )
insert dbo.foo ( name ) values ( 'charlie' )
insert dbo.foo ( name ) values ( 'delta' )
insert dbo.foo ( name ) values ( 'echo' )
insert dbo.foo ( name ) values ( 'foxtrot' )
go
create table dbo.bar
(
id int not null identity(1,1) primary key clustered ,
foo_id int null foreign key references dbo.foo(id) ,
name varchar(32) not null unique nonclustered ,
)
go
insert dbo.bar( foo_id , name ) values( 1 , 'golf' )
insert dbo.bar( foo_id , name ) values( 5 , 'hotel' )
insert dbo.bar( foo_id , name ) values( 3 , 'india' )
insert dbo.bar( foo_id , name ) values( 5 , 'juliet' )
insert dbo.bar( foo_id , name ) values( 6 , 'kilo' )
go
查询
select *
from dbo.foo foo
left join dbo.bar bar on bar.foo_id = foo.id
order by bar.foo_id, foo.id
产生以下结果集:
id name id foo_id name
-- ------- ---- ------ -------
2 bravo NULL NULL NULL
4 delta NULL NULL NULL
1 alpha 1 1 golf
3 charlie 3 3 india
5 echo 2 5 hotel
5 echo 4 5 juliet
6 foxtrot 5 6 kilo
(7 row(s) affected)
此应该允许查询优化器使用合适的索引(如果存在);但是,它确实不保证,而不是使用任何此类索引。
答案 3 :(得分:0)
你能试试吗?
SELECT TOP 100
(columns snipped)
FROM dbo.Files AS e1
LEFT OUTER JOIN dbo.Records AS e2 ON e1.FID = e2.FID
ORDER BY e2.ID ASC
这应该会给你e2.ID首先为空的位置。另外,请确保将Records.ID编入索引。这应该给你你想要的订单。