应该在给定表上索引哪些字段?

时间:2008-12-22 14:36:59

标签: sql-server indexing

我有一张包含大量寄存器的表(超过200万)。这是一个事务表,但我需要一个包含大量连接的报告。什么是对该表进行索引的最佳实践,因为它耗费了太多时间。

我正在使用storedprocedure分页方法对表进行分页,但我需要一个索引,因为当我想导出报表时,我需要在没有分页的情况下获取整个查询并获取总记录,我需要全部选择。

任何帮助?

8 个答案:

答案 0 :(得分:11)

如果启用“包含实际执行计划”,SQL Server 2008 Management Studio查询工具将告诉您给定查询需要快速运行的索引。 (假设有一个明显缺失的索引使查询运行异常缓慢,那就是。)

SQL Server 2008 Management Studio Query Screenshot http://img208.imageshack.us/img208/4108/image4sy8.png

我们一直在Stack Overflow上使用它。这是SQL 2008的最佳功能之一。它也适用于较旧的SQL实例,只需安装SQL 2008工具并将它们指向SQL 2005实例即可。不过,不确定它是否适用于任何事情。

正如其他人所说,您也可以手动执行此操作,但需要一些试验和错误。您将需要在ORDER BY和WHERE子句中使用的字段上的索引。

答案 1 :(得分:4)

  

关键领域必须是永恒的   where子句???

不,那太过分了。索引字段实际上只有在a)WHERE子句足够有选择性时(即:仅选择约1-2%的值;“性别”字段上的索引,它只能是两个或三个可能值中的一个)没有意义),和b)你的WHERE子句不涉及函数调用或其他魔法。

在您的情况下,TBL.Status 可能成为候选人 - 有多少可能的值?您选择“1”和“2”值 - 如果有数百个可能的值,那么这是一个不错的选择。

旁注: 这个子句:(TBL.Login IS NULL和TBL.Login<>'dev')是没有意义的 - 如果TBL.login的值为NULL,那么它肯定不是'dev'.....所以只是“IS NULL”将绰绰有余......

您可能要考虑放置索引的其他字段是TBL.Date,因为您似乎在这里选择了一系列日期 - 这可能是一个不错的选择。

另外,一般情况下:尽可能不要使用SELECT * FROM ......来选择字段。这会导致SQL Server的大量开销。指定你的专栏 - 并且只选择那些你真正需要的专栏 - 而不仅仅是所有这些专栏......

答案 2 :(得分:1)

检查您的查询,并找到用于匹配它们的字段。那些通常是最好的候选人!

答案 3 :(得分:1)

SQL Server有一个可以帮助您的“数据库引擎优化顾问”。这不适用于SQL Server Express,但适用于所有其他版本的SQL Server。

  • 在查询窗口中加载查询。
  • 在菜单上,点击查询 - >分析数据库引擎中的查询 调整顾问

调优顾问将识别可添加到表中的索引以提高性能。根据我的经验,调优顾问并不总是有所帮助,但大部分时间都是如此。这是我建议你开始的地方。

答案 4 :(得分:1)

好的这是执行中的查询

    SELECT 
        TBL.*
    FROM
        FOREINGDATABASE..TABLENAME TBL
            LEFT JOIN Status S 
                    ON TBL.Status = S.Number
    WHERE
    (TBL.ID = CASE @Reference WHEN 0 THEN TBL.ID ELSE @Reference END) AND
    TBL.Date >= @FechaInicial AND 
    TBL.Date <= @FechaFinal AND
    (TBL.Channel = CASE @Canal WHEN '' THEN TBL.Channel ELSE @Canal END)AND
    (TBL.DocType = CASE @TipoDocumento WHEN '' THEN TBL.DocType ELSE @TipoDocumento END)AND
    (TBL.Document = CASE @NumDocumento WHEN '' THEN TBL.Document ELSE @NumDocumento END)AND
    (TBL.Login = CASE @Login WHEN '' THEN TBL.Login ELSE @Login END)AND
    (TBL.Login IS NULL AND TBL.Login <> 'dev' )  AND
    TBL.Status IN ('1','2')

关键字段必须在where子句???

中进行

答案 5 :(得分:0)

如果我没有记错的话,请纠正我,如果我,我认为你应该在where子句的条件字段上创建非聚集索引。 (也许这可以作为获得索引的一些候选者的起点。)

祝你好运

答案 6 :(得分:0)

如果执行索引扫描而不是搜索,原因可能是字段在索引中的顺序不正确。

答案 7 :(得分:0)

将索引放在您要加入和过滤的所有列上。 索引的使用也取决于索引列的选择性。 最好的方法是向我们展示您的查询,以便我们可以尝试改进它。