我試圖在SQL Server中編寫查詢,但它對具有大約3000萬行(TGS_INFO)的表執行表掃描,因此查詢運行速度非常緩慢。SQL Server未使用索引
實際的查詢比較複雜,但是我將它簡化爲一個更簡單的版本,但仍然存在相同的問題。
SELECT DISTINCT UNIT_ITEMS.DBKEY,
UNIT_ITEMS.ID,
UNIT_ITEMS.LOCATION1,
UNIT_ITEMS.LOCATION2
FROM UNIT_ITEMS
INNER JOIN TGS.dbo.TGS_INFO
ON UNIT_ITEMS.UNIT_ID = TGS_INFO.UNIT_ID AND
UNIT_ITEMS.ITEM_ID = TGS_INFO.ITEM_ID AND
UNIT_ITEMS.LOCATION1 = TGS_INFO.LOCATION1 AND
UNIT_ITEMS.LOCATION2 = TGS_INFO.LOCATION2
這是執行計劃。
StmtText
|--Sort(DISTINCT ORDER BY:([DbName].[dbo].[UNIT_ITEMS].[DBKEY] ASC, [DbName].[dbo].[UNIT_ITEMS].[ITEM_ID] ASC, [DbName].[dbo].[UNIT_ITEMS].[LOCATION1] ASC, [DbName].[dbo].[UNIT_ITEMS].[LOCATION2] ASC))
|--Hash Match(Inner Join, HASH:([DbName].[dbo].[UNIT_ITEMS].[UNIT_ID], [DbName].[dbo].[UNIT_ITEMS].[ITEM_ID], [DbName].[dbo].[UNIT_ITEMS].[LOCATION1], [DbName].[dbo].[UNIT_ITEMS].[LOCATION2])=([Expr1008], [Expr1009], [Expr1010], [Expr1011]), RESIDUAL:([DbName].[dbo].[UNIT_ITEMS].[UNIT_ID]=[Expr1008] AND [DbName].[dbo].[UNIT_ITEMS].[ITEM_ID]=[Expr1009] AND [DbName].[dbo].[UNIT_ITEMS].[LOCATION1]=[Expr1010] AND [DbName].[dbo].[UNIT_ITEMS].[LOCATION2]=[Expr1011]))
|--Table Scan(OBJECT:([DbName].[dbo].[UNIT_ITEMS]))
|--Compute Scalar(DEFINE:([Expr1008]=CONVERT_IMPLICIT(int,[TGS].[dbo].[TGS_INFO].[UNIT_ID],0), [Expr1009]=CONVERT_IMPLICIT(nvarchar(50),[TGS].[dbo].[TGS_INFO].[ITEM_ID],0), [Expr1010]=CONVERT_IMPLICIT(nvarchar(50),[TGS].[dbo].[TGS_INFO].[LOCATION1],0), [Expr1011]=CONVERT_IMPLICIT(int,[TGS].[dbo].[TGS_INFO].[LOCATION2],0)))
|--Table Scan(OBJECT:([TGS].[dbo].[TGS_INFO]))
TGS_INFO和UNIT_ITEMS在UNIT_ID和ITEM_ID上都有非聚簇索引。如前所述,TGS_INFO有大約3000萬行,但它們均勻地分佈在大約一千個不同的UNIT_ID上。 UNIT_ITEMS始終只包含一個UNIT_ID。
這裏有指標:
CREATE NONCLUSTERED INDEX [IX_UNIT_ID_ITEM_ID] ON [dbo].[TGS_INFO]
(
[UNIT_ID] ASC,
[ITEM_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [IX_UNIT_ID_ITEM_ID] ON [dbo].[UNIT_ITEMS]
(
[UNIT_ID] ASC,
[ITEM_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
正如我在評論中所提到的,所有的列是VARCHAR(50)TGS_INFO。 UNIT_ITEMS中的所有列都是整數。
爲了記錄,我沒有設計TGS_INFO的模式。
每個表只能有一個聚簇索引。什麼是您的指數的列順序? – Kermit
對,哈希似乎不對。你也嘗試過沒有DISTINCT?這是DISTINCT真的有必要嗎? –
您所匹配的所有列中的數據類型是否匹配?我不明白爲什麼它會進行隱式數據轉換。如果將'UNIT_ITEMS.LOCATION1 = TGS_INFO.LOCATION1 AND UNIT_ITEMS.LOCATION2 = TGS_INFO.LOCATION2'移動到'WHERE'子句怎麼辦? –