比较查询

Dan*_*ews 2 performance sql-server query-performance

在 SQL Server 中,如果您要比较来自两个查询的统计 IO,您如何确保缓存不会成为一个因素?

例如(我是在打字的时候编的,不是一个真实的例子):

SELECT Type,
    NAME
FROM TableA a
LEFT OUTER JOIN TableB b ON a.id = b.id
WHERE b.id IS NULL ;

SELECT Type,
    NAME
FROM TableA a 
WHERE NOT EXISTS (
        SELECT 1
        FROM tableb
        WHERE id = a.id
        ) ;
Run Code Online (Sandbox Code Playgroud)

我现在做什么:我以这种方式运行它,获取一个新连接(新 SID)并像这样运行它(以相反的顺序):

SELECT Type,
    NAME
FROM TableA a 
WHERE NOT EXISTS (
        SELECT 1
        FROM tableb
        WHERE id = a.id
        ) ;

SELECT Type,
    NAME
FROM TableA a
LEFT OUTER JOIN TableB b ON a.id = b.id
WHERE b.id IS NULL ;
Run Code Online (Sandbox Code Playgroud)

有没有更好的办法?

事后补充资料

这是假设您不是系统管理员。

Aar*_*and 6

假设 tableA 和 tableB 中的数据永远不会在缓存中是否现实?当所有数据都必须从磁盘中提取时,系统上运行的查询的百分比是多少?

关于测试查询和比较它们有两种思路:

  1. 使用冷缓存运行它们(在每次查询之前清除缓存/缓冲区等)
  2. 使用热缓存运行它们(在开始比较指标之前,您首先通过多次运行查询来填充缓存)

因为理想情况下,在现实世界的场景中,您将在大多数情况下处理 2. 大多数情况下,在 1 上花费太多精力似乎相对无济于事。除非您处于生产环境内存非常低的情况下,在这种情况下我宁愿花钱购买更多内存,而不是尝试比较和调整总是依赖于物理 I/O 的查询的劳动力成本。我认为 2. 的实际测试比 1. 更有用,同样在大多数情况下。

如果您真的想这样做,我想您可以用其他表中的数据强制填充缓冲区,取代这两个表中的数据。尽管我真的很担心在没有系统管理员权限的系统上过多地修改这种方式(这可能正是出于这个原因,或者至少是其中一个原因)。

另一个建议是:备份数据库,然后将其恢复到您系统管理员的系统。这可能是在处理不同的 I/O 子系统,但除了纯 I/O 性能的差异之外,查询之间的相对差异应该仍然有助于比较何时可以自由释放缓存和缓冲区。