SELECT *
FROM network_listen
WHERE node_code IN (
SELECT DISTINCT node_code
FROM view_Log_Network_circsByUnit
WHERE status = '1'
)
OR node_code = (
SELECT TOP 1 nodeCode
FROM TransmissionUnit_LocalInfo
)
AND node_code <> (
SELECT parentNodeCode
FROM TransmissionUnit_RouterInfo
WHERE nodeCode = (
SELECT TOP 1 nodeCode
FROM TransmissionUnit_LocalInfo
)
);
Log_Network_circs (48 萬筆) 做 GROUP BY node_code 取 MAX(end_time) 再 LEFT JOIN 回原表 —— **缺乏支援索引**。CREATE VIEW [dbo].[view_Log_Network_circsByUnit] AS
SELECT B.*
FROM (
SELECT node_code, MAX(end_time) AS end_time
FROM Log_Network_circs
GROUP BY node_code
) A
LEFT OUTER JOIN dbo.Log_Network_circs B
ON A.node_code = B.node_code
AND A.end_time = B.end_time;
CREATE TABLE [dbo].[Log_Network_circs](
[log_id] [varchar](30) NOT NULL PRIMARY KEY CLUSTERED,
[node_code] [varchar](100) NULL,
[node_name] [varchar](100) NULL,
[server_name] [varchar](100) NULL,
[start_time] [datetime] NULL,
[end_time] [datetime] NULL,
[status] [varchar](30) NULL
) ON [PRIMARY];
視圖核心存取路徑:GROUP BY node_code + MAX(end_time) + JOIN ON node_code, end_time。
建立複合非叢集索引:
CREATE NONCLUSTERED INDEX [IX_Log_Network_circs_node_end]
ON [dbo].[Log_Network_circs] (node_code ASC, end_time ASC)
WITH (SORT_IN_TEMPDB = ON, ONLINE = ON); -- Enterprise 版可 ONLINE
資料庫引擎調優顧問 (DTA) 同步建議:建立統計資料 _dta_stat_... (end_time, node_code) 與相同欄位順序的非叢集索引。
| 指標 | 優化前 | 優化後 | 改善幅度 |
|---|---|---|---|
| Log_Network_circs 邏輯讀取 | 13,558 | 9 | 99.9% ↓ |
| CPU 時間 | 719 ms | 0 ms | 100% ↓ |
| 經過時間 | 719 ms | 2 ms | 99.7% ↓ |
其他資料表 (TransmissionUnit_*, network_listen) 邏輯讀維持個位數,無變化。
GROUP BY a, MAX(b) + JOIN ON a, b → INDEX (a, b) 即可覆蓋排序、分組、聯結。STATISTICS IO 邏輯讀與 STATISTICS TIME CPU/經過時間是最客觀的改善證據。此案例以單一複合索引解決高 CPU 問題,證明「找對存取路徑、建立正確索引」往往比重寫 SQL 更高效。建議建立定期 索引維護 (重組/重建) + 統計資料更新 排程,防止統計過期導致計畫退化。