繁体   English   中英

SQL语句 - 如何通过索引提高速度

[英]SQL Statement - How can Improve speed with indexing

我有一个脚本,必须查看超过250万条记录,以查找是否有未读电子邮件的成员。 我想知道如何提高速度。 目前,运行脚本最多可能需要8秒钟:

SELECT TOP(1) MemberMailID
FROM MemberMail
WHERE ToReadFlag = 0
AND ToMemberID = 102
AND ToDeletedFlag = 0
AND FromDeletedFlag = 0
AND OnHold = 0
AND ToArchivedFlag = 0

如何使用索引加快速度?

此索引可能会有所帮助,但请记住,没有免费午餐(必须维护索引,因此这将影响您的插入/更新/删除工作负载):

CREATE NONCLUSTERED INDEX unread_emails
  ON dbo.MemberMail(ToMemberID)
  INCLUDE (MemberMailID)
  WHERE ToReadFlag = 0
  AND ToDeletedFlag = 0
  AND FromDeletedFlag = 0
  AND OnHold = 0
  AND ToArchivedFlag = 0;

现在您的查询可以说:

SELECT TOP (1) MemberMailID
  FROM dbo.MemberMail -- dbo prefix
    WITH (INDEX (unread_emails)) -- in case you need to force, though you should not
WHERE ToMemberID = 102
AND ToReadFlag = 0
AND ToDeletedFlag = 0
AND FromDeletedFlag = 0
AND OnHold = 0
AND ToArchivedFlag = 0
ORDER BY ToMemberID; -- ORDER BY is important!

如果根据查询更改其中某些标志的值,您可以尝试将这些列添加到索引的键而不是过滤器,例如,假设您有时检查OnHold = 0 ,有时OnHold = 1

CREATE NONCLUSTERED INDEX unread_emails
  ON dbo.MemberMail(ToMemberID, OnHold)
  INCLUDE (MemberMailID)
  WHERE ToReadFlag = 0
  AND ToDeletedFlag = 0
  AND FromDeletedFlag = 0
  AND ToArchivedFlag = 0;

您可能还想尝试在密钥中使用MemberMailID而不是INCLUDE 例如:

CREATE NONCLUSTERED INDEX unread_emails
  ON dbo.MemberMail(ToMemberID, MemberMailID)
  WHERE ToReadFlag = 0
  AND ToDeletedFlag = 0
  AND FromDeletedFlag = 0
  AND OnHold = 0
  AND ToArchivedFlag = 0;

这些差异可能与您的数据和使用模式无关,但您将能够比我们能够猜测的更容易地测试差异。

看起来像是过滤索引的一个很好的候选者。

过滤索引是优化的非聚簇索引,尤其适用于覆盖从明确定义的数据子集中进行选择的查询。 它使用过滤谓词来索引表中的一部分行。 与全表索引相比,精心设计的筛选索引可以提高查询性能,降低索引维护成本并降低索引存储成本。

这些方面的东西:

CREATE NONCLUSTERED INDEX IX_MemberMail_ToMemberId_Unread
ON dbo.MemberMail (ToMemberId ASC)
WHERE ToReadFlag = 0
AND ToDeletedFlag = 0
AND FromDeletedFlag = 0
AND OnHold = 0
AND ToArchivedFlag = 0;

通过SSMS中的(CTRL + M)获取实际查询计划 或者将您的查询粘贴到SSMS中,右键单击它,选择在数据库引擎优化顾问中分析查询 ,您将看到需要添加的索引。 基本上,您需要复合+包含索引。

作为一个经验法则, 场在其上进行频繁的过滤器( where的条件)必须建立索引。

同样,作为拇指规则,我遵循以下标准:

  1. 必须为每个关键字段(主要或外部)编制索引
  2. 必须对我必须执行频繁查找的每个date字段编制索引
  3. 虽然我避免使用它,但如果我需要对charvarchar字段执行频繁搜索,我也会对它们进行索引

请注意,很容易陷入索引所有内容的诱惑。 不要这样做。 小心并设计具有最佳成本 - 收益关系的索引。

我是MySQL用户,我不知道如何在SQL服务器中执行此操作,但必须有一种方法来显示查询的执行计划(在MySQL中它explain select... )。 尝试显示执行计划,然后根据需要确定索引所需的字段。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM