Sql 如何改进具有700万行的表的本机查询?

Sql 如何改进具有700万行的表的本机查询?,sql,sql-server,nativequery,Sql,Sql Server,Nativequery,我的数据库(SQL SERVER)中有以下视图(表) 我想从这个表中检索两件东西 具有每个产品编号的最新预订日期的对象。 它将返回对象={0001,219-06-06 10:39:58}和{0003,219-06-07 12:39:58} 如果所有步骤编号没有产品编号的预订日期,它将返回步骤编号为1的对象。它将返回对象={0002,1,NULL} 该视图有7.000.000行。我必须使用本机查询来完成 检索具有最新预订日期的产品的第一个查询: SELECT DISTINCT * FROM

我的数据库(SQL SERVER)中有以下视图(表)

我想从这个表中检索两件东西

  • 具有每个产品编号的最新预订日期的对象。 它将返回对象={0001,219-06-06 10:39:58}和{0003,219-06-07 12:39:58}
  • 如果所有步骤编号没有产品编号的预订日期,它将返回步骤编号为1的对象。它将返回对象={0002,1,NULL}
该视图有7.000.000行。我必须使用本机查询来完成

检索具有最新预订日期的产品的第一个查询:

SELECT DISTINCT *
FROM TABLE t
WHERE t.BOOKING_DATE = (SELECT max(tbl.BOOKING_DATE) FROM TABLE tbl WHERE t.PRODUCT_NUMBER = tbl.PRODUCT_NUMBER)
第二个查询检索预订日期为空且步骤号为1的产品

SELECT DISTINCT *
FROM TABLE t
WHERE (SELECT max(tbl.BOOKING_DATE) FROM TABLE tbl WHERE t.PRODUCT_NUMBER = tbl.PRODUCT_NUMBER) IS NULL AND t.STEP_NUMBER = 1
我尝试使用一个查询,但它花费的时间太长。 现在我使用2查询来获取这些信息,但将来我需要改进这一点。你有别的选择吗?我也不能使用SQL SERVER内部的存储过程、函数。我必须使用来自Java的本机查询来完成它

按正确顺序尝试
行编号()。sql server按顺序将空值视为可能的最低值

SELECT TOP(1) WITH TIES *
FROM myTable t
ORDER BY row_number() over(partition by PRODUCT_NUMBER order by BOOKING_DATE DESC, STEP_NUMBER);
请注意sql server建议的索引以获得良好的性能。

请使用正确的顺序尝试
行号()。sql server按顺序将空值视为可能的最低值

SELECT TOP(1) WITH TIES *
FROM myTable t
ORDER BY row_number() over(partition by PRODUCT_NUMBER order by BOOKING_DATE DESC, STEP_NUMBER);
请注意sql server建议的索引以获得良好的性能。

试试这个

Declare @p table(pumber int,step int,bookdate datetime)
insert into @p values 
(1,1,'2019-01-01'),(1,2,'2019-01-02'),(1,3,'2019-01-03')
,(2,1,null),(2,2,null),(2,3,null)
,(3,1,null),(3,2,null),(3,3,'2019-01-03')

;With CTE as
(
select pumber,max(bookdate)bookdate 
from @p p1 
where bookdate is not null
group by pumber
)

select p.* from @p p
where exists(select 1 from CTE c 
where p.pumber=c.pumber and p.bookdate=c.bookdate)
union all
select p1.* from @p p1
where p1.bookdate is null and step=1
and not exists(select 1 from CTE c 
where p1.pumber=c.pumber)
若性能是主要关注点,那个么1或2个查询并不重要,最后是性能问题

Create NonClustered index ix_Product on Product (ProductNumber,BookingDate,Stepnumber)
Go
如果超过90%的数据是
,其中BookingDate不为null
其中BookingDate为null
,则可以在其上创建筛选索引

 Create NonClustered index ix_Product on Product (ProductNumber,BookingDate,Stepnumber)
where BookingDate is not null
 Go
试试这个

Declare @p table(pumber int,step int,bookdate datetime)
insert into @p values 
(1,1,'2019-01-01'),(1,2,'2019-01-02'),(1,3,'2019-01-03')
,(2,1,null),(2,2,null),(2,3,null)
,(3,1,null),(3,2,null),(3,3,'2019-01-03')

;With CTE as
(
select pumber,max(bookdate)bookdate 
from @p p1 
where bookdate is not null
group by pumber
)

select p.* from @p p
where exists(select 1 from CTE c 
where p.pumber=c.pumber and p.bookdate=c.bookdate)
union all
select p1.* from @p p1
where p1.bookdate is null and step=1
and not exists(select 1 from CTE c 
where p1.pumber=c.pumber)
若性能是主要关注点,那个么1或2个查询并不重要,最后是性能问题

Create NonClustered index ix_Product on Product (ProductNumber,BookingDate,Stepnumber)
Go
如果超过90%的数据是
,其中BookingDate不为null
其中BookingDate为null
,则可以在其上创建筛选索引

 Create NonClustered index ix_Product on Product (ProductNumber,BookingDate,Stepnumber)
where BookingDate is not null
 Go

最有效的方法可能是关联子查询:

select t.*
from t
where t.step_number = (select top (1) t2.step_number
                       from t t2
                       where t2.product_number = t.product_number and
                       order by t2.booking_date desc, t2.step_number
                      );

特别是,这可以利用
(产品编号、预订日期描述、步骤编号)上的索引

最有效的方法可能是相关子查询:

select t.*
from t
where t.step_number = (select top (1) t2.step_number
                       from t t2
                       where t2.product_number = t.product_number and
                       order by t2.booking_date desc, t2.step_number
                      );

特别是,这可以利用
上的索引(产品编号、预订日期描述、步骤编号)

添加索引对我很有帮助。感谢帮助了我。谢谢