在我开始之前,我想说,我对这个Sql索引事件完全不熟悉。
我有一张表没有加入任何东西。它包含以下列:
Id (int)
String1 (nvarchar(10)
String2 (nvarchar(50)
DateTime1 (date)
DateTime2 (date)
DateTime3 (date)
我在该表上有大约100,000,000行。并且对它进行搜索非常慢,所以我想我必须添加一些索引。
我只会运行以下查询:
查询1
select * from Table
where String1 = "Blah" and
String 2 = "Blah" and
DateTime1 <= {someTime1} and
DateTime2 >= {someTime1}
查询2
select * from Table
where String1 = "Blah" and
String 2 = "Blah" and
DateTime2 >= {someTime1}
查询3
select * from Table
where String1 = "Blah" and
String 2 = "Blah" and
DateTime3 >= {someTime1}
请注意,除了日期比较略有不同之外,它们几乎是相同的查询。此外,排序不是问题。
所以我尝试在列String1,String2,DateTime1,DateTime2上添加非聚集索引。运行查询1 这是我看到的:
所以这是我的问题:
谢谢,
志
答案 0 :(得分:2)
解析和编译查询,也许从磁盘读取。这就是它第二次快速运行的原因。当参数改变时,需要花时间再次编译。
数据缓存。又名缓冲池。一般来说,SQL Server通常不会出现更多RAM。
查询1和2相同,查询3不同。
我建议以
开头的2个索引关于数据类型的其他想法......如果课程
,则越小越好编辑:
磁盘读取将在内存中发生(简单地),因此更多RAM将有所帮助 但是,我怀疑20秒是编译+统计等,而不是从磁盘读取
答案 1 :(得分:0)
我建议您熟悉SQL Server的数据库调优顾问(DTA)和Profiler。
这是一篇好文章:
http://www.zimbio.com/SQL/articles/655/How+Tune+Database+Using+Database+Tuning+Advisor
DTA并不总能给你完美的推荐,但它通常是一个好的开始。如果您使用分析器,您可以监视数据库一天,然后将其传递给DTA。
还有其他需要考虑的因素,例如:
请记住,拥有索引会减慢插入和更新。
要做的另一件重要事情是确保从运行的每个查询开始,从相同的基线开始。我怀疑你在问题中看到了1和2的结果,因为你已经缓存了数据。 Here is a good link介绍测试sql脚本的方式。
答案 2 :(得分:0)
查询1的问题在于它有两个独立的范围条件。最近有一个非常相似的问题。我在那里解释了那个特殊的问题:How Database stores data internally in B-Tree/B+Tree
关于查询2:
如果您使用以下索引:
String1, String2, Date2, Date 1
它可以很好地为query2提供服务,并且不会更改query1(除了date1上的条件比date2更具选择性)。
query3可能需要一个额外的索引:
String1, String2, Date3
但是,我不喜欢两个具有相同前缀的索引。我可能会转向String1和String2 - 以防某些查询只有String2。
想要更好地理解所有这些索引的内容吗?看看我的free eBook "Use The Index, Luke"
答案 3 :(得分:0)
- &GT;我认为你做得很好,但我也会在你的查询中看到数据选择性。 在100,000,000个典型查询中返回的记录数量是多少? 如果结果集很小(占整个表的3~5%),则索引是很好的分辨率。
答案 4 :(得分:0)
根据您安装SQL Server的操作系统,SQL Server的版本以及已有的RAM数量,更多RAM将有所帮助。它们对RAM都没有相同的限制。
供将来参考使用SQL Server Management Studio(SSMS)中的Database Tuning Advisor中的Analyze Query。你现在可能不需要它,但是当表变得更复杂时可能会有所帮助。
这张桌子上有主键吗?只是好奇,你从来没有提过它。