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

标签 sql sql-server sql-server-2008

我有一个脚本,它必须查看超过 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;

您可能还想尝试在 key 中使用 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;

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

关于SQL 语句 - 如何通过索引提高速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15621128/

相关文章:

sql - FOR XML PATH (' ' ) 的含义是什么?

sql-server - SQL Server 2012 内联表值函数返回空行

c# - TransactionScope 和手动回滚事务之间的区别?

php - Mysqli 查询在 phpmyadmin 中工作但不在脚本中

sql - 在 ORACLE 中,有没有一种方法可以使用两个表将多行行连接成一个行,其中最终值用逗号分隔?

mysql - 我们可以为 mysql 和某些特定数据库保留相同的密码吗?

java - Spring Boot项目和com.microsoft.sqlserver.jdbc.SQLServerException : The "variant" data type is not supported

SQLite 按所选日期范围内的所有日期进行分组,即使数据不存在

c# - 从 SQL Server 2008 到 C# 的地理函数(多边形/ map 区域内部或外部的纬度和经度点)

database - 两个不同的数据库(数据从一个复制到另一个)并比较它们的数据