我发现了一个非常奇怪的行为,我必须解释。我们有一个简单的表格,大约有450.000个条目(MSSQL 2008 R2)。MSSQL:为什么这个索引比其他索引快10倍?
此表的索引是很简单的:
指数#1包含:
[OwnerUserID] -> int, 4 byte
[TargetQuestionID] -> int, 4 byte
[LastChange] -> date, 8 byte
指数#2包含:
[LastChange] is a date, 8 byte
[OwnerUserID] is an int, 4 byte
[TargetQuestionID] is an int, 4 byte
正如你所看到的,所不同的只是列的顺序略有不同;在这两个指标中,叶子的大小相同,16个字节(远离我见过做的非常大的数据库,一些DBA的)
的查询很简单:
Query #1:
- Asks just for the last entried element (top(1)) ordered by LastChange, so it takes only LastChange into account
Query #2:
- Asks just for the last entried element (top(1)) entried for a distinct OwnerUserID, so it takes OwnerUserID and LastChange into account
结果是:
指数#1查询#1超级慢,虽然我认为这应该是OK,因为数据叶子是真的不大(16个字节)
指数#2是用于查询#2超慢(但由于它需要考虑两个值,OwnerUserID + LastChange = 8个字节,我没有看到任何为什么它应该更慢/更快)
我们的想法是只有一个索引,但由于每个查询方案的性能相差10-11倍,我们最终并行创建了这两个索引的两个,我们认为我们可以选择其中一个 - 因为这个指数并不是那么大/复杂,你会认为这个列顺序上的细微差别会受到伤害。
所以,现在我们是在浪费一倍的空间,因为该表由每天1万行左右的增长,我们将磁盘空间问题的地方在未来...
起初,我以为这是因为一些内部NHibernate的问题,但我们检查了性能监视器,结果是绝对可重现的。
好像与指标MSSQL性能高度依赖的datetime-列的使用,因为这个简单的例子表明,这可能崩溃全性能: -/
检查执行计划。 –
嘿嘿,那是真的 - 我们只检查了SQL分析器,看看它需要多长时间,但不是执行计划: -/ – johngrinder