Sql 如何改进具有700万行的表的本机查询?
我的数据库(SQL SERVER)中有以下视图(表) 我想从这个表中检索两件东西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
- 具有每个产品编号的最新预订日期的对象。 它将返回对象={0001,219-06-06 10:39:58}和{0003,219-06-07 12:39:58}
- 如果所有步骤编号没有产品编号的预订日期,它将返回步骤编号为1的对象。它将返回对象={0002,1,NULL}
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
);
特别是,这可以利用上的索引(产品编号、预订日期描述、步骤编号)
添加索引对我很有帮助。感谢帮助了我。谢谢