SQL 服务器 - 插入新数据会降低查询性能
SQL Server - Inserting new data worsens query performance
我们有一个 4-5TB SQL 服务器数据库。最大的 table 大约有 800 GB,包含 1 亿行。 4-5 个其他类似的 table 是这个大小的 1/3-2/3。我们经历了创建新索引以优化性能的过程。虽然性能确实有所提高,但我们发现新插入的数据查询速度最慢。
这是一个财务报告应用程序,带有在数据库之上运行的 BI 工具。尽管大部分数据是在早上 7 点之前加载的,但数据会在深夜继续加载一整夜。用户早上8点左右开始通过BI工具查询数据,最关心的是最新(每日)的数据。
我想知道新插入的数据是否会导致索引乱序。有什么我们可以做的,以便我们在新插入的数据上获得比旧数据更好的性能。我希望我已经在这里很好地解释了这个问题。如果有任何遗漏信息,请告诉我。谢谢
编辑 1
让我描述一下架构。
我有一个基础 table(我们称它为基础),其中 Date,id 作为聚簇索引。
它有大约 50 列
然后我们有5个derived tables (Derived1, Derived2,...) ,根据不同的metric类型,它们也有Date,Id作为聚簇索引和Base table上的外键约束。
表 Derived1 和 Derived2 有 350 多列。 Derived3、4、5 有大约 100-200 列。由于 BI 工具的限制,创建了一个大视图来连接所有数据 table。日期、ID 是所有 table 连接形成视图的连接列(因此我在这些列上创建了聚簇索引)。主要关注的是 BI 工具的性能。 BI 工具总是使用视图,并且通常向服务器发送类似的查询。
在其他过滤列上还有其他索引。
主要问题仍然存在——如何防止性能下降。
另外我想知道
- 如果 NCI on Date,ID 在所有 tables 上除了在 date,ID 上的聚簇索引之外更好。
- 对于派生的 table,将 150 列包含在 NCI 中是否有意义?
这是一个广泛的问题,尤其是在不了解您的系统的情况下。但是我会尝试的一件事是在完成加载数据后手动更新 indexes/table 上的统计信息。对于这么大的表,您不太可能操作足够多的行来触发自动更新。如果没有干净的统计数据,SQL 服务器将不会有您的数据的准确直方图。
接下来,深入研究您的执行计划,看看哪些运算符成本最高。
您有大约 1 亿行,每天都在增加新部分,而这些新部分通常是 selected。我应该使用带有这些数字的分区索引而不是常规索引。
sql 服务器中的解决方案是分区。看看sql分区,看能不能采纳。分区是集群的一种形式,其中数据组共享一个物理块。例如,如果您使用年份和月份,则所有 2018-09 记录将共享相同的物理 space 并且很容易找到。因此,如果您 select 使用这些过滤器(以及更多)的记录,它就像 table 具有 2018-09 记录的大小。这并不完全准确,但很像。小心分区的数据值 - 与每个值都是唯一的标准 PK 集群相反,分区列应该产生一组很好的不同的唯一组合,因此分区。
如果您不能使用分区,则必须使用常规索引自行创建 'partitions'。这将需要一些实验。基本思想是数据(一个数字?)表示例如。一波或一组导入数据波。就像今天和下一个导入的数据一样10 天将是波“1”。接下来的 10 天将是“2”,依此类推。过滤最新的,例如10 波,你在最近的 100 天导入有效地跳过所有其余数据。粗略地说,如果您将现有的 1 亿行划分为 100 个波浪并从第 101 波浪开始并搜索第 90 波或更大的波浪,那么如果 SQL 被正确放置以首先使用新索引(最终会做的)
我们有一个 4-5TB SQL 服务器数据库。最大的 table 大约有 800 GB,包含 1 亿行。 4-5 个其他类似的 table 是这个大小的 1/3-2/3。我们经历了创建新索引以优化性能的过程。虽然性能确实有所提高,但我们发现新插入的数据查询速度最慢。
这是一个财务报告应用程序,带有在数据库之上运行的 BI 工具。尽管大部分数据是在早上 7 点之前加载的,但数据会在深夜继续加载一整夜。用户早上8点左右开始通过BI工具查询数据,最关心的是最新(每日)的数据。
我想知道新插入的数据是否会导致索引乱序。有什么我们可以做的,以便我们在新插入的数据上获得比旧数据更好的性能。我希望我已经在这里很好地解释了这个问题。如果有任何遗漏信息,请告诉我。谢谢
编辑 1
让我描述一下架构。 我有一个基础 table(我们称它为基础),其中 Date,id 作为聚簇索引。 它有大约 50 列 然后我们有5个derived tables (Derived1, Derived2,...) ,根据不同的metric类型,它们也有Date,Id作为聚簇索引和Base table上的外键约束。
表 Derived1 和 Derived2 有 350 多列。 Derived3、4、5 有大约 100-200 列。由于 BI 工具的限制,创建了一个大视图来连接所有数据 table。日期、ID 是所有 table 连接形成视图的连接列(因此我在这些列上创建了聚簇索引)。主要关注的是 BI 工具的性能。 BI 工具总是使用视图,并且通常向服务器发送类似的查询。
在其他过滤列上还有其他索引。 主要问题仍然存在——如何防止性能下降。 另外我想知道
- 如果 NCI on Date,ID 在所有 tables 上除了在 date,ID 上的聚簇索引之外更好。
- 对于派生的 table,将 150 列包含在 NCI 中是否有意义?
这是一个广泛的问题,尤其是在不了解您的系统的情况下。但是我会尝试的一件事是在完成加载数据后手动更新 indexes/table 上的统计信息。对于这么大的表,您不太可能操作足够多的行来触发自动更新。如果没有干净的统计数据,SQL 服务器将不会有您的数据的准确直方图。
接下来,深入研究您的执行计划,看看哪些运算符成本最高。
您有大约 1 亿行,每天都在增加新部分,而这些新部分通常是 selected。我应该使用带有这些数字的分区索引而不是常规索引。 sql 服务器中的解决方案是分区。看看sql分区,看能不能采纳。分区是集群的一种形式,其中数据组共享一个物理块。例如,如果您使用年份和月份,则所有 2018-09 记录将共享相同的物理 space 并且很容易找到。因此,如果您 select 使用这些过滤器(以及更多)的记录,它就像 table 具有 2018-09 记录的大小。这并不完全准确,但很像。小心分区的数据值 - 与每个值都是唯一的标准 PK 集群相反,分区列应该产生一组很好的不同的唯一组合,因此分区。
如果您不能使用分区,则必须使用常规索引自行创建 'partitions'。这将需要一些实验。基本思想是数据(一个数字?)表示例如。一波或一组导入数据波。就像今天和下一个导入的数据一样10 天将是波“1”。接下来的 10 天将是“2”,依此类推。过滤最新的,例如10 波,你在最近的 100 天导入有效地跳过所有其余数据。粗略地说,如果您将现有的 1 亿行划分为 100 个波浪并从第 101 波浪开始并搜索第 90 波或更大的波浪,那么如果 SQL 被正确放置以首先使用新索引(最终会做的)