簡體   English   中英

SQL Server為什么索引不與OR一起使用

[英]SQL Server why is index not used with OR

我一直在研究索引並試圖了解它們的工作原理以及如何使用它們來提高性能,但我遺漏了一些東西。

我有下表:

| Id | Name | Email | Phone |
| 1  | John |  E1   |  P1   |
| 2  | Max  |  E2   |  P2   |

我正在嘗試找到索引EmailPhone列的最佳方法,因為查詢將(大部分時間)是表格的形式

[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]使用索引掃描。

我還嘗試創建多個索引:一個包含兩列,一個用於電子郵件,一個用於電子郵件。 在這種情況下,[2]和[3]使用seek,但[1]繼續使用scan。

為什么數據庫不能使用索引或? 考慮到查詢,該表的最佳索引方法是什么?

為每列創建單獨的索引。
通過使用提示,我們可以強制優化器使用/不使用索引,因此您可以檢查執行計划,了解所涉及的性能並了解每個路徑的含義。

瀏覽我的演示並考慮以下場景中每條路徑所涉及的工作 -

  1. 只有少數行滿足條件j = 123。
    只有少數行滿足條件k = 456。

  2. 大多數行滿足條件j = 123。
    大多數行滿足條件k = 456。

  3. 只有少數行滿足條件j = 123。
    大多數行滿足條件k = 456。

試着想一下你為每個場景選擇的路徑。
請隨時提問。


演示

;with t(n) as (select 0 union all select n+1 from t where n < 999)

select      1+t0.n+1000*t1.n                                as i
           ,floor(rand(cast (newid() as varbinary))*1000)   as j
           ,floor(rand(cast (newid() as varbinary))*1000)   as k 

into        t

from        t t0,t t1 

option       (maxrecursion 0)
;

create index t_j on t (j);
create index t_k on t (k);

update statistics t (t_j)
update statistics t (t_k)

掃描

select      *
from        t (forcescan)
where       j = 123
        or  k = 456
  • 這很簡單。

在此輸入圖像描述

尋求

select      *
from        t (forceseek)
where       j = 123
        or  k = 456
  • “索引尋求” :正在尋找每個指數的相關值(123和456)
  • “合並連接” :結果(行ID)正在連接(如在UNION ALL中)
  • “Stream Aggregate” :正在刪除重復的行ID
  • “Rid Lookup” + “嵌套循環” :行ID用於從表中檢索行(t)

在此輸入圖像描述

使用兩個單獨的索引,一個在(email) ,一個在(phone, email)

OR非常困難。 如果您的條件通過AND而不是OR連接,那么您的索引將用於第一個查詢(但不是第三個查詢,因為phone不是索引中的第一個鍵)。

您可以將查詢編寫為:

SELECT *
FROM Person 
WHERE Email = '...' 
UNION ALL
SELECT *
FROM Person 
WHERE Email <> '...' AND Phone = '...';

SQL Server應為每個子查詢使用適當的索引。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM