我正在.NET和SQL Server 2008中编写应用程序。我正在使用快速版。
我有一个带有VARCHAR主键的数据库表。该表有大约1000万条记录。
Id:VARCHAR(76),此列上的主键,聚簇索引
HitDice:VARCHAR(83)
我在这个表上运行了一个简单的查询
SELECT HitDice from TABLE WHERE Id = @Id;
我花了整个查询执行时间的平均时间,发现查询大约花了8毫秒来检索记录。
虽然对于许多应用程序来说这可能足够快,但对我来说这太慢了(请参阅我的附加说明,了解为什么这太慢了)。我需要将它降低一个数量级。
我尝试创建一个计算列,用于散列VARCHAR主键和索引。我在http://csliu.com/2007/07/hash-index-in-microsoft-sql-server找到了这个建议。
我还尝试更改查询以一次返回多条记录而不是一条记录。
我的新表格如下:
Id:VARCHAR(76),主键
HitDice:VARCHAR(83)
IdHash:Int,计算列= CHECKSUM(Id),此列上的非聚集索引
我的查询现在看起来像这样:
SELECT Id,HitDice from dbo.BlotExposures WHERE IdHash IN (CHECKSUM(@Id1),CHECKSUM(@Id2),CHECKSUM(@Id3),...,CHECKSUM(@Idn)) AND Id IN (@Id1,@Id2,...,@Idn);
这种方法对前一个查询的执行稍好一些,大约7毫秒/记录。
由于我没有太多的数据库经验,我的一个问题是我不知道我当前的执行时间是否合理。在<中执行查询是否合理? 1ms /记录?
如果是,我该怎么办?我需要更好的硬件吗?或者还有其他我可以尝试的东西吗?
一些补充说明:
我已经对应用程序进行了分析,发现我们大约有40%的时间用于执行此查询。因此,我确信这是瓶颈。
我正在使用内存缓存,但问题是通常不会在任何合理的时间内多次检索记录。虽然我没有对此做过太多分析,但我估计只有30%的缓存项目可以重复使用。
给出一些关于我为什么说这个查询太慢的背景。我正在编程一个学习玩双陆棋的神经网络。每回合一次,查询需要多次运行,并且需要为神经网络学习数十万个游戏。让我们假设我每回合需要50条记录,每场比赛有40回合。 8毫秒/记录和10万场比赛,18天完成。如果我设法将查询降低到大约1毫秒,那就是2天。节省了很多。
执行计划。第一个查询执行计划非常简单。聚集索引查找的成本为100%。第二个查询在非聚集索引查找上使用50%的成本,在RID查找上使用50%。
编辑:
根据要求,我正在为第一个查询的实例添加url和执行计划。运行需要73毫秒。请参阅http://tinypic.com/view.php?pic=2ko7kp&s=8#.U7HVSPmSzPo
答案 0 :(得分:3)
假设您的数据库存储在传统硬盘上,那么在您查询内存中的记录(例如您自己的缓存,数据库缓存或磁盘缓存)的情况下,它就会被绑定来自磁盘。这只能在磁盘上查找它的速度。根据{{3}},大多数常见桌面驱动器的平均搜索时间通常约为9毫秒。这似乎符合你的观察。
对此的解决方案是
答案 1 :(得分:0)
如果您已经有很多基于此设计的代码,您可能希望将数据库切换到MySql并使用内存表选项。如果你能负担得起内存,那么应该跑得非常快。如果你没有记忆,建议你留意。