我一直在研究索引并试图了解它们的工作原理以及如何使用它们来提高性能,但我遗漏了一些东西。
我有下表:
人:
| Id | Name | Email | Phone |
| 1 | John | E1 | P1 |
| 2 | Max | E2 | P2 |
我正在尝试找到索引列的最佳方法 Email
和Phone
考虑到查询(大多数时候)的形式为
[1] SELECT * FROM Person WHERE Email = '...' OR Phone = '...'
[2] SELECT * FROM Person WHERE Email = ...
[3] SELECT * FROM Person WHERE Phone = ...
我认为最好的方法是使用两列创建单个索引:
CREATE NONCLUSTERED INDEX [IX_EmailPhone]
ON [dbo].[Person]([Email], [PhoneNumber]);
但是,对于上面的索引,只有查询 [2] 受益于索引查找,其他查询则使用索引扫描。
我还尝试创建多个索引:一个包含两列,一个用于电子邮件,一个用于电子邮件。在这种情况下,[2]和[3]使用seek,但[1]继续使用scan。
为什么数据库不能使用带有 or 的索引?考虑到查询,该表的最佳索引方法是什么?
最佳答案
使用两个单独的索引,一个针对(电子邮件)
,另一个针对(电话、电子邮件)
。
OR
相当困难。如果您的条件通过 AND
而不是 OR
连接,那么您的索引将用于第一个查询(但不是第三个查询,因为 phone
不是索引中的第一个键)。
您可以将查询编写为:
SELECT *
FROM Person
WHERE Email = '...'
UNION ALL
SELECT *
FROM Person
WHERE Email <> '...' AND Phone = '...';
SQL Server 应为每个子查询使用适当的索引。
关于SQL Server 为什么索引不与 OR 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40874599/