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

How can I improve the native query for a table with 7 millions rows?

我的数据库(SQL 服务器)中有以下视图(table)。

我想从这个 table 中检索 2 个东西。

视图有 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)

第二个查询检索预订日期为 NULL 且步数 = 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 的本机查询来完成它。

尝试 row_number() 正确排序。 sql-server ORDER BY.

将 Null 值视为可能的最低值
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- 服务器建议的索引以获得良好的性能。

试试这个,

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% 的数据是 where BookingDate is not nullwhere BookingDate is 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
                      );

特别是,这可以利用 (product_number, booking_date desc, step_number) 上的索引。