varchar列

时间:2016-05-28 00:45:50

标签: sql sql-server database performance indexing

我将通过声明我绝不是SQL专家来解释这个问题。

但是,我正在尝试处理我们的数据库正在发生的事情。我们一直在使用一段代码来查询服务器数据库,该数据库已经运行多年了。

最近,我们遇到了超时错误。该数据库多年来一直在增长,但仍然相对较小(该表有大约5000万条记录)。

我怀疑桌子已经太大了,我们的非专业设置数据库无法处理。所以我尝试在表SQL Management Studio上运行以下简单查询:

SELECT * 
FROM [dbo].[Table] 
WHERE [Variable] = 'NNNNNNNN12'

变量设置为varchar(50)。此查询需要30-60秒才能完成。这对我来说似乎太过分了。我们在软件上运行类似的查询,默认超时为15秒。

稍微深入一点,我意识到桌子上没有指定主键。所以我做了一个,但令我惊讶的是它让它慢了。相同的查询现在需要大约5秒钟。

我接下来尝试的是添加varchar列的索引,但这又使得速度变慢 - 再增加10秒。添加全文索引使得响应时间几乎一分钟就更糟了。

我唯一能做的就是让它变慢 - 所以我需要你的帮助。我甚至在这里正确的轨道?这种类型的查询是否合理30秒?关于我可以尝试的任何其他想法?

3 个答案:

答案 0 :(得分:1)

很好,你用索引包解决了性能问题。如果发现性能问题蔓延,您可以尝试重新组织或重建索引。

我有一个包含聚簇索引的大约1000万行的表,随着时间的推移,Sql Server 2005(以及我们升级后的2008)继续恢复使用它,即使我创建了一个上面的索引,其中包括所涉及的主要列SELECT。最初一切都很好,执行计划正在使用新索引,但几周后我们的查询将再次开始计时,我们发现Sql Server再次使用聚簇索引扫描。

我们从未了解过为什么会发生这种情况,但可靠的解决方法是重建索引并更新统计信息。

ALTER INDEX ALL ON dbo.[Table] REBUILD
UPDATE STATISTICS dbo.[Table]

对于我们来说,这很快 - 5到10分钟 - 但首先在生产数据库的副本上试一试,看看你的情况需要多长时间。

随着时间的推移,索引可能会变得支离破碎。它们从对应于连续键的页面开始在物理上在一起,并且每个页面填充到FILLFACTOR设置。使用插入或删除时,可能会有页面拆分。逻辑相关的页面不再是物理上在一起的,而不是100%的一页,你有2页,50%的使用率。您可以在磁盘上跳转更多以检索数据,并且还有更多半空页面需要加载。

您可以使用

检查碎片
declare @db_id int = db_id('stackoverflow'); 
select db_name(database_id), object_name(object_id), *
from sys.dm_db_index_physical_stats ( @db_id, null, NULL, NULL, 'DETAILED' ) 

avg_fragmentation_in_percent应尽可能接近零,以获得最佳性能。 avg_page_space_used_in_percent是所有页面中使用的可用数据存储空间的平均百分比,应该很高。

答案 1 :(得分:-1)

请查看以下脚本以获得一些指导..

        //calculate the distance
        ...
        Console.WriteLine("Distance : " + Math.Sqrt(deltaX + deltaY));

        //calculate the angle
        double angle = Math.Atan2(point2Y - point1Y, point2X - point1X);
        ...
        Console.WriteLine(angle + " Rad");
        Console.WriteLine(angle * 180 / Math.PI + " Deg");

需要考虑的问题:

  • 输出结果中是否需要所有列?
  • 执行期间是否有任何Varbinary或varchar(max)sql类型? (如果我们将它们包括在内,表现会很慢)
  • 您可以添加更多过滤器,以便在执行计划中涉及更多索引吗?

答案 2 :(得分:-1)

对于此查询:

Select * FROM [dbo].[Table] where [Variable] = 'NN12345'

您需要一个索引:

create index idx_table_variable on table(variable);

然后,有一些警告。 variable和常量值需要具有相同的类型和排序规则。因此,如果您有索引并且上述查询不使用索引,则可能会发生其他情况(例如表列与服务器或数据库的默认值之间的排序规则不兼容)。