Sql Server索引在没有连接和可预测查询的表上

时间:2010-11-02 17:39:35

标签: sql sql-server indexing performance

在我开始之前,我想说,我对这个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 这是我看到的:

  1. 现在速度要快得多,但加载时间大约需要20秒。
  2. 我注意到,对于完全相同的查询(具有相同的搜索参数),如果我再次调用它,它将在不到一秒的时间内返回数​​据。
  3. 我注意到如果我使用其他一些参数运行查询1,它将再次需要20秒才能加载。
  4. 我注意到我的RAM在查询后上升并保持不变。
  5. 所以这是我的问题:

    1. 我这样做了吗?为什么加载需要20秒?添加索引后,它不应该非常快吗?
    2. 什么是Sql server对我的RAM做什么?我需要更多内存,因为我有一张大桌子吗?
    3. 我是否需要为查询2和查询3添加新索引?或者我添加的索引已经足够用于其他2个查询?
    4. 谢谢,

5 个答案:

答案 0 :(得分:2)

  1. 解析和编译查询,也许从磁盘读取。这就是它第二次快速运行的原因。当参数改变时,需要花时间再次编译。

  2. 数据缓存。又名缓冲池。一般来说,SQL Server通常不会出现更多RAM。

  3. 查询1和2相同,查询3不同。

  4. 我建议以

    开头的2个索引
    • String1,String 2,DateTime2,DateTime1 INCLUDE DateTime3
    • String1,String 2,DateTime3 INCLUDE DateTime2,DateTime1

    关于数据类型的其他想法......如果课程

    ,则越小越好

    编辑:

    磁盘读取将在内存中发生(简单地),因此更多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)

  1. 我这样做了吗?为什么加载需要20秒?添加索引后不应该很快吗?
  2. - &GT;我认为你做得很好,但我也会在你的查询中看到数据选择性。 在100,000,000个典型查询中返回的记录数量是多少? 如果结果集很小(占整个表的3~5%),则索引是很好的分辨率。

    1. 什么是Sql server对我的RAM做什么?我需要更多内存,因为我有一张大桌子吗? - &GT; DBMS正在将数据(逐块)从物理存储移动到RAM以执行查询。此外,您的查询需要解析,它会占用一些内存。

答案 4 :(得分:0)

根据您安装SQL Server的操作系统,SQL Server的版本以及已有的RAM数量,更多RAM将有所帮助。它们对RAM都没有相同的限制。

供将来参考使用SQL Server Management Studio(SSMS)中的Database Tuning Advisor中的Analyze Query。你现在可能不需要它,但是当表变得更复杂时可能会有所帮助。

这张桌子上有主键吗?只是好奇,你从来没有提过它。