jre*_*121 4 performance sql-server sql-server-2008-r2 index-tuning
我的公司使用一个软件套件,其中我唯一可以真正修改的是数据库。我们一直有性能问题(主要是我们希望尽快解决的硬件问题),但最近在特定区域特别糟糕 - 当它应该小于 5 时加载需要 20-120 秒。我承担了一些用户,在他们(和我的)机器上进行了跟踪,这似乎是有问题的查询:
SELECT s.create_timestamp, s.create_timestamp, s.create_timestamp_tz, s.row_timestamp, log_msg, pre_mod, post_mod, u.first_name, u.mi, u.last_name, log_id
FROM log_events s (NOLOCK), user_mstr u (NOLOCK)
WHERE s.organization_id = '00001'
AND source1_id = @account_id --Place holder for a client account unique id
AND source2_id IS NULL
AND source3_id IS NULL
AND source4_id IS NULL
AND s.created_by = u.user_id
Run Code Online (Sandbox Code Playgroud)
我知道 NOLOCK很糟糕,但我无法控制。
它仅在每个新 source1_id 的第一次滞后 - 之后的每次执行都更快 - 而且随着行数的增加,情况似乎变得更糟。我使用尚未运行的 source1_id 手动运行查询SET STATISTICS IO/TIME ON,它返回了中小行数(490),结果如下:
Table 'user_mstr'. Scan count 0, logical reads 6948, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'log_events'. Scan count 1, logical reads 13939, physical reads 1221, read-ahead reads 34, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 46 ms, elapsed time = 18751 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
Run Code Online (Sandbox Code Playgroud)
log_events 表很大(31,847,167 行),用作整个数据库中重大更改的更改/审核日志。这是表和简化索引的创建语句:
CREATE TABLE log_events (
log_event_id UNIQUEIDENTIFIER NOT NULL,
organization_id CHAR(5) NOT NULL,
site_id CHAR(4) NULL,
source1_id UNIQUEIDENTIFIER NULL,
source2_id UNIQUEIDENTIFIER NULL,
source3_id UNIQUEIDENTIFIER NULL,
source4_id UNIQUEIDENTIFIER NULL,
event_source_type CHAR(2) NOT NULL,
log_id CHAR(4) NOT NULL,
log_msg VARCHAR(4000) NOT NULL,
pre_mod VARCHAR(1000) NULL,
post_mod VARCHAR(1000) NULL,
create_timestamp DATETIME NOT NULL CONSTRAINT DFlog_events_create_timestamp DEFAULT (GETDATE()),
created_by INT NOT NULL,
modify_timestamp DATETIME NOT NULL CONSTRAINT DFlog_events_modify_timestamp DEFAULT (GETDATE()),
modified_by INT NOT NULL,
row_timestamp TIMESTAMP,
group_id INT NULL,
create_timestamp_tz SMALLINT NULL,
modify_timestamp_tz SMALLINT NULL,
CONSTRAINT pk_log_events PRIMARY KEY NONCLUSTERED (log_event_id) WITH (FILLFACTOR = 90) ON MAINSYSTEM_INDEX_1
)
--Simplified Indices:
INDEX inx_log_events1 ON log_events (source1_id, source2_id, source3_id, source4_id)
INDEX inx_log_events3 ON log_events (source1_id, source2_id, event_source_type)
INDEX inx_log_events4 ON log_events (site_id, source2_id, source1_id)
INDEX inx_log_events5 ON log_events (source1_id, event_source_type, site_id, log_event_id)
CLUSTERED INDEX inx_log_events7 ON log_events (create_timestamp, event_source_type)
INDEX inx_log_events8 ON log_events (site_id, source2_id, event_source_type, log_id)
INDEX inx_log_events9 ON log_events (organization_id, site_id, source1_id, source2_id, source3_id, source4_id, event_source_type)
Run Code Online (Sandbox Code Playgroud)
user_mstr 表不是很大,user_id 字段是一个 PK。
在索引方面我是新手,所以我的问题是:
与实际时间相比,CPU 时间很小。
第二次运行查询时,速度很快——大概是一旦数据在 RAM 中(这是从第二次运行中受益的少数事情之一)。
在我看来,问题不是 SQL,而是磁盘。请注意 PAGEIOLATCH 在您的查询运行时等待增加。看看这方面发生了什么。与您的 SAN 人员交谈。查明是否有其他磁盘活动正在进行。查看是否正在重建 RAID 5 或 6 磁盘。
| 归档时间: |
|
| 查看次数: |
898 次 |
| 最近记录: |