在我工作的地方,数据库已被触及"一些不再在这里工作的人。某些数据库视图运行速度非常慢。我认为这是因为它使用了许多JOINS和UNIONS。在我看来应该有一个更有效的方法来做到这一点。原谅我在这方面缺乏知识。
SELECT s.id AS 'ShipmentID',
s.tracking_no AS 'Tracking Number',
c.name AS 'Client Name',
...
many more
...
FROM shipments_archive s
left join client c on c.id = s.client
left join DIM_ClientCompany cc on cc.client_id = s.client
left join company co on co.company_id = cc.company_id
left join weekof wo on CAST(s.date_shipped AS DATE) = CAST(wo.mydate AS DATE)
left join DIM_ResolutionCodes res on res.Resolution_Key = s.resolutions
WHERE
co.company_name NOT IN ('client1', 'client2')
UNION ALL
SELECT s.id AS 'ShipmentID',
s.tracking_no AS 'Tracking Number',
c.name AS 'Client Name',
...
many more
...
FROM shipments_archive s
left join client c on c.id = s.client
left join DIM_ClientCompany cc on cc.client_id = s.client
left join company co on co.company_id = cc.company_id
left join weekof wo on CAST(s.date_shipped AS DATE) = CAST(wo.mydate AS DATE)
left join DIM_ResolutionCodes res on res.Resolution_Key = s.resolutions
WHERE co.company_name IN ('Client3', 'Client4')
UNION ALL
SELECT s.id AS 'ShipmentID',
s.tracking_no AS 'Tracking Number',
c.name AS 'Client Name',
...
many more
...
FROM shipments_archive s
left join client c on c.id = s.client
left join DIM_ClientCompany cc on cc.client_id = s.client
left join company co on co.company_id = cc.company_id
left join DIM_Pharmacy p on p.company_id = co.company_id and p.[Lookup] = s.shipper
left join weekof wo on CAST(s.date_shipped AS DATE) = CAST(wo.mydate AS DATE)
left join DIM_ResolutionCodes res on res.Resolution_Key = s.resolutions
WHERE co.company_name IN ('Client5')
UNION ALL
您是否可以使用 GOTO 或 CASE 语句。为每个客户端多次提取此数据似乎非常耗时。有超过500万条记录。任何帮助将不胜感激。
答案 0 :(得分:0)
从索引的角度来看,正如评论所示,查看执行计划将为如何优化此查询的索引提供一些很好的见解。从TSQL的角度来看,我不喜欢在多次使用的语句中看到相同的内容。一种选择是使用表变量。它将使用更多内存但保存IO。话虽如此,我会检查UNION ALL语句,因为看起来这个查询将返回重复记录(公司名称不在1& 2中,公司名称不在3& 4中,都返回客户端5的记录)。
--This will create a table in memory and populate it from the source tables. This way, you only read the source tables once.
DECLARE @table_variable TABLE (
ShipmentID INT
,TrackingNumber INT
,etc...)
INSERT @table_variable (ShipmentID, TrackingNumber, etc...)
SELECT
s.id AS 'ShipmentID'
,s.tracking_no AS 'Tracking Number'
,c.name AS 'Client Name'
--...
--many more
--...
FROM shipments_archive s
left join client c on c.id = s.client
left join DIM_ClientCompany cc on cc.client_id = s.client
left join company co on co.company_id = cc.company_id
left join weekof wo on CAST(s.date_shipped AS DATE) = CAST(wo.mydate AS DATE)
left join DIM_ResolutionCodes res on res.Resolution_Key = s.resolutions
--You then select from the table in memory for your subsets.
SELECT
ShipmentID
,TrackingNumber
,etc...
--...
--many more
--...
FROM @table_variable
WHERE company_name NOT IN ('client1', 'client2')
UNION ALL
SELECT
ShipmentID
,TrackingNumber
,etc...
--...
--many more
--...
FROM @table_variable
WHERE company_name NOT IN ('client3', 'client4')
UNION ALL
SELECT
ShipmentID
,TrackingNumber
,etc...
--...
--many more
--...
FROM @table_variable
WHERE company_name NOT IN ('client5')