sys.dm_db_partition_stats.row_count 在为每个 table 获取 Azure SQL 数据库行数时有多不准确?
How inaccurate can the sys.dm_db_partition_stats.row_count be in getting an Azure SQL DB row count for each table?
我看到过一些关于 sys.dm_db_partition_stats.row_count
如何由于提供对象的统计信息而不是实际执行 COUNT()
而产生不准确结果的一般性陈述。但是,我一直无法找到这些陈述背后的任何更深层原因,也无法在我的 Azure SQL 数据库中验证假设。
所以我想学习-
- 这种方法实际上有多不准确?
- 为什么结果可能会出现偏差?
(例如,统计信息每天仅在特定对象操作时重新计算一次)。
非常感谢任何相关的见解!
我能够自己找到几件事 -- 主要是通过 运行 包含 sys.dm_db_partition_stats.row_count
的各种查询,同时知道每个 table 中的实际行数。
这是最后一个 查询 我想出了
这变得快速并且(在我的例子中)每个 table 的准确行计数,从高计数到低计数。
SELECT
(SCHEMA_NAME(A.schema_id) + '.' + A.Name) as table_name,
B.object_id, B.index_id, B.row_count
FROM
sys.dm_db_partition_stats B
LEFT JOIN
sys.objects A
ON A.object_id = B.object_id
WHERE
SCHEMA_NAME(A.schema_id) <> 'sys'
AND (B.index_id = '0' OR B.index_id = '1')
ORDER BY
B.row_count DESC
WHERE
子句的第一行用于排除系统 table,例如sys.plan_persist_wait_stats
和许多其他人。
第二行处理非唯一的非聚集索引(它们是对象,显然有自己的统计信息)-> 如果你不过滤掉它们,你会得到索引的双行计数 tables 在查询输出中使用 GROUP BY A.schema_id, A.Name
或两个具有相同 table_name
的记录时(如果不使用 GROUP BY
)
很高兴您找到了解决方案并自行解决。您的新版本应该是一个答案。我只是帮助你 post 它作为答案,这可能对其他社区成员有益:
我自己发现的几件事 -- 主要是通过 运行 包含 sys.dm_db_partition_stats.row_count
的各种查询,同时知道每个 table.[=16] 中的实际行数=]
这是我提出的最后一个查询
这变得快速并且(在我的例子中)每个 table 的准确行数,从高数到低数排序。
SELECT
(SCHEMA_NAME(A.schema_id) + '.' + A.Name) as table_name,
B.object_id, B.index_id, B.row_count
FROM
sys.dm_db_partition_stats B
LEFT JOIN
sys.objects A
ON A.object_id = B.object_id
WHERE
SCHEMA_NAME(A.schema_id) <> 'sys'
AND (B.index_id = '0' OR B.index_id = '1')
ORDER BY
B.row_count DESC
WHERE
子句的第一行用于排除系统 table,例如sys.plan_persist_wait_stats 和许多其他人。
第二行处理非唯一的非聚集索引(它们是对象,显然有自己的统计信息)-> 如果你不过滤掉它们,你会得到索引的双行计数 tables 在查询输出中使用 GROUP BY A.schema_id, A.Name
或两个具有相同 table_name
的记录时(如果不使用 GROUP BY
)
再次感谢您的分享。
感谢@conor 的commnet:“如果你想看看数字可以相差多远,我建议你尝试做用户事务,插入一堆行,然后回滚事务。”
我看到过一些关于 sys.dm_db_partition_stats.row_count
如何由于提供对象的统计信息而不是实际执行 COUNT()
而产生不准确结果的一般性陈述。但是,我一直无法找到这些陈述背后的任何更深层原因,也无法在我的 Azure SQL 数据库中验证假设。
所以我想学习-
- 这种方法实际上有多不准确?
- 为什么结果可能会出现偏差?
(例如,统计信息每天仅在特定对象操作时重新计算一次)。
非常感谢任何相关的见解!
我能够自己找到几件事 -- 主要是通过 运行 包含 sys.dm_db_partition_stats.row_count
的各种查询,同时知道每个 table 中的实际行数。
这是最后一个 查询 我想出了
这变得快速并且(在我的例子中)每个 table 的准确行计数,从高计数到低计数。
SELECT
(SCHEMA_NAME(A.schema_id) + '.' + A.Name) as table_name,
B.object_id, B.index_id, B.row_count
FROM
sys.dm_db_partition_stats B
LEFT JOIN
sys.objects A
ON A.object_id = B.object_id
WHERE
SCHEMA_NAME(A.schema_id) <> 'sys'
AND (B.index_id = '0' OR B.index_id = '1')
ORDER BY
B.row_count DESC
WHERE
子句的第一行用于排除系统 table,例如sys.plan_persist_wait_stats
和许多其他人。
第二行处理非唯一的非聚集索引(它们是对象,显然有自己的统计信息)-> 如果你不过滤掉它们,你会得到索引的双行计数 tables 在查询输出中使用 GROUP BY A.schema_id, A.Name
或两个具有相同 table_name
的记录时(如果不使用 GROUP BY
)
很高兴您找到了解决方案并自行解决。您的新版本应该是一个答案。我只是帮助你 post 它作为答案,这可能对其他社区成员有益:
我自己发现的几件事 -- 主要是通过 运行 包含 sys.dm_db_partition_stats.row_count
的各种查询,同时知道每个 table.[=16] 中的实际行数=]
这是我提出的最后一个查询 这变得快速并且(在我的例子中)每个 table 的准确行数,从高数到低数排序。
SELECT
(SCHEMA_NAME(A.schema_id) + '.' + A.Name) as table_name,
B.object_id, B.index_id, B.row_count
FROM
sys.dm_db_partition_stats B
LEFT JOIN
sys.objects A
ON A.object_id = B.object_id
WHERE
SCHEMA_NAME(A.schema_id) <> 'sys'
AND (B.index_id = '0' OR B.index_id = '1')
ORDER BY
B.row_count DESC
WHERE
子句的第一行用于排除系统 table,例如sys.plan_persist_wait_stats 和许多其他人。
第二行处理非唯一的非聚集索引(它们是对象,显然有自己的统计信息)-> 如果你不过滤掉它们,你会得到索引的双行计数 tables 在查询输出中使用 GROUP BY A.schema_id, A.Name
或两个具有相同 table_name
的记录时(如果不使用 GROUP BY
)
再次感谢您的分享。
感谢@conor 的commnet:“如果你想看看数字可以相差多远,我建议你尝试做用户事务,插入一堆行,然后回滚事务。”