【发布时间】:2009-04-16 06:27:13
【问题描述】:
我们使用 SQL Server 2005 来跟踪大量不断传入的数据(每秒 5-15 次更新)。在它投入生产几个月后,我们注意到其中一个表已经开始花费大量时间来查询。
表格有 3 列:
-
id-- 自动编号(集群) -
typeUUID-- 在插入发生之前生成的 GUID;用于将类型组合在一起 -
typeName-- 类型名称 (duh...)
我们运行的其中一个查询在 typeName 字段上是不同的:
SELECT DISTINCT [typeName] FROM [types] WITH (nolock);
typeName 字段上有一个非聚集、非唯一的升序索引。该表目前包含大约 2 亿条记录。当我们运行这个查询时,查询用了 5m 58s 才返回!也许我们不了解索引是如何工作的……但我认为我们并没有对它们有太多误解。。
为了进一步测试,我们运行了以下查询:
SELECT DISTINCT [typeName] FROM (SELECT TOP 1000000 [typeName] FROM [types] WITH (nolock)) AS [subtbl]
这个查询在大约 10 秒后返回,正如我所料,它正在扫描表。
这里有什么我们遗漏的吗?为什么第一个查询需要这么长时间?
编辑:啊,对不起,第一次查询返回 76 条记录,谢谢九边。
跟进:谢谢大家的回答,现在对我来说更有意义(我不知道为什么以前没有......)。如果没有索引,它会跨 200M 行进行表扫描,使用索引,它会跨 200M 行进行索引扫描...
SQL Server 确实更喜欢索引,它确实提供了一点性能提升,但没有什么值得兴奋的。重建索引确实将查询时间从 6m 缩短到 3m 多一点,这是一个改进,但还不够。我只是要向我的老板推荐我们规范化表结构。
再次感谢大家的帮助!!
【问题讨论】:
-
您通常期望有多少种不同的类型?
-
老实说,听起来您的设计存在根本缺陷。 “传入”表中有 200M 条记录?在它们出现一段时间后,你不能把它们推到别的地方吗?在不了解您的应用程序的情况下很难提供更好的建议,但听起来您可能需要进行一些认真的重构。
-
是的,我们确实有很多数据正在处理,目前是 4 个月的数据。我们需要对数据进行分区,但我们还没有做到。
-
我无法思考 typeUUID 列实际上可能对什么有用......将它与 200M 行、20 次插入/秒的基数 76 的单列索引结合起来,并声称“性能问题”,这在我看来就是“回到绘图板”:(
-
>>但是应该颠倒差异,因为第一个>>查询使用的是索引 NO - 它不是。如果您将所有行扫描到 DISTINCT 上,您将始终进行全表扫描 - 没有索引会对此有所帮助。
标签: sql sql-server sql-server-2005