1

关于这个特定的查询:

不要期望理解被查询的数据:它是无关紧要的。

看看WHERE 子句

SELECT 
    de.DocumentEntryId,
    de.Number,
    currentdev.ToIgnore,
    previousdev.ToIgnore,
    currentdev.DocumentEntryValueId AS CurrentDocumentEntryValueId, 
    SUM(currentper.Value) AS CurrentPaymentRate,
    SUM(currentdevr.ConversionRate) AS CurrentConversionRate,
    MAX(previousdev.DocumentEntryValueId) AS PreviousDocumentEntryValueId,
    SUM(previousper.Value) AS PreviousPaymentRate,
    SUM(previousdevr.ConversionRate) AS PreviousConversionRate
FROM 
    DocumentEntry de
    INNER JOIN PaymentEntry currentpe ON currentpe.PaymentEntryId = de.CurrentPaymentEntryId
    INNER JOIN DocumentEntryValue currentdev ON currentpe.DocumentEntryValueId = currentdev.DocumentEntryValueId
    INNER JOIN DocumentEntryValue previousdev ON previousdev.DocumentEntryId = de.DocumentEntryId
    INNER JOIN PaymentEntryRate currentper ON currentpe.PaymentEntryId = currentper.PaymentEntryId
    INNER JOIN DocumentEntryValueRate currentdevr ON currentdev.DocumentEntryValueId = currentdevr.DocumentEntryValueId
    INNER JOIN PaymentEntry previouspe ON previousdev.DocumentEntryValueId = previouspe.DocumentEntryValueId
    INNER JOIN PaymentEntryRate previousper ON previouspe.PaymentEntryId = previousper.PaymentEntryId
    INNER JOIN DocumentEntryValueRate previousdevr ON previousdevr.DocumentEntryValueId = previousdev.DocumentEntryValueId
WHERE 
    previousdev.DocumentEntryValueId <> currentdev.DocumentEntryValueId
    AND currentdev.ToIgnore <> 1
    AND previousdev.ToIgnore <> 1
    AND currentpe.PaymentId = previouspe.PaymentId
GROUP BY 
    de.DocumentEntryId, 
    de.Number,
    currentdev.ToIgnore,
    previousdev.ToIgnore,
    currentdev.DocumentEntryValueId
ORDER BY DocumentEntryId

尤其是这两个不等式

AND currentdev.ToIgnore <> 1
AND previousdev.ToIgnore <> 1

注意:ToIgnore 是一个位列。

此查询大约需要 10 秒才能返回大约 1300 行。

但是,如果我将这两行更改为使用相等运算符:

AND currentdev.ToIgnore = 0
AND previousdev.ToIgnore = 0

归还任何东西都需要永远。

它有帮助,这里是每个表的索引:

DocumentEntry索引:

ALTER TABLE [dbo].[DocumentEntry] ADD  CONSTRAINT [DocumentEntry$0] PRIMARY KEY CLUSTERED 
(
    [DocumentEntryId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Data Filegroup 1]

CREATE NONCLUSTERED INDEX [IDX_DOCUMENTENTRY_REFNUMBER] ON [dbo].[DocumentEntry]
(
    [EntryReferenceNumber] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Data Filegroup 1]

CREATE NONCLUSTERED INDEX [missing_index_14227] ON [dbo].[DocumentEntry]
(
    [MasterDocumentEntryId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Data Filegroup 1]

CREATE NONCLUSTERED INDEX [missing_index_186297_186296_DocumentEntry] ON [dbo].[DocumentEntry]
(
    [Number] ASC
)
INCLUDE (   [DocumentEntryId]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Data Filegroup 1]

DocumentEntryValue索引:

ALTER TABLE [dbo].[DocumentEntryValue] ADD  CONSTRAINT [DocumentEntryValue$0] PRIMARY KEY CLUSTERED 
(
    [DocumentEntryValueId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Data Filegroup 1]

CREATE NONCLUSTERED INDEX [IDX_DOCUMENTENTRYVALUE_DOCENTRYID] ON [dbo].[DocumentEntryValue]
(
    [DocumentEntryId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Data Filegroup 1]


CREATE NONCLUSTERED INDEX [IDX_DOCUMENTENTRYVALUE_REFNUMBER] ON [dbo].[DocumentEntryValue]
(
    [EntryValueReferenceNumber] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Data Filegroup 1]


CREATE NONCLUSTERED INDEX [missing_index_4022_4021_DocumentEntryValue] ON [dbo].[DocumentEntryValue]
(
    [ReferenceDocumentId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Data Filegroup 1]

DocumentEntryValueRate索引:

ALTER TABLE [dbo].[DocumentEntryValueRate] ADD  CONSTRAINT [DocumentEntryValueRate$0] PRIMARY KEY CLUSTERED 
(
    [DocumentEntryValueRateId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Data Filegroup 1]


CREATE NONCLUSTERED INDEX [missing_index_56865_56864_DocumentEntryValueRate] ON [dbo].[DocumentEntryValueRate]
(
    [DocumentEntryValueId] ASC
)
INCLUDE (   [timestamp],
    [DocumentEntryValueRateId],
    [RateId],
    [RateVersionId],
    [RateTypeId],
    [RateGroupId],
    [RatePeriodValueId],
    [ConversionRate]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Data Filegroup 1]

PaymentEntry索引:

ALTER TABLE [dbo].[PaymentEntry] ADD  CONSTRAINT [PaymentEntry$0] PRIMARY KEY CLUSTERED 
(
    [PaymentEntryId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Data Filegroup 1]

CREATE NONCLUSTERED INDEX [IDX_PAYMENTENTRY_DOCENTRYVALUEID] ON [dbo].[PaymentEntry]
(
    [DocumentEntryValueId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Data Filegroup 1]

CREATE NONCLUSTERED INDEX [missing_index_2517_2516_PaymentEntry] ON [dbo].[PaymentEntry]
(
    [PaymentId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Data Filegroup 1]

PaymentEntryRate索引:

ALTER TABLE [dbo].[PaymentEntryRate] ADD  CONSTRAINT [PaymentEntryRate$0] PRIMARY KEY CLUSTERED 
(
    [PaymentEntryRateId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Data Filegroup 1]

CREATE NONCLUSTERED INDEX [IDX_PAYMENTENTRYRATE_PAYMENTENTRYID] ON [dbo].[PaymentEntryRate]
(
    [PaymentEntryId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Data Filegroup 1]

CREATE NONCLUSTERED INDEX [missing_index_2618_2617_PaymentEntryRate] ON [dbo].[PaymentEntryRate]
(
    [RateId] ASC
)
INCLUDE (   [timestamp],
    [PaymentEntryRateId],
    [PaymentEntryId],
    [RateTypeId],
    [RateGroupId],
    [RateVersionId],
    [RatePeriodValueId],
    [Value]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Data Filegroup 1]

CREATE NONCLUSTERED INDEX [missing_index_2686_2685_PaymentEntryRate] ON [dbo].[PaymentEntryRate]
(
    [RateTypeId] ASC,
    [RateId] ASC,
    [RatePeriodValueId] ASC
)
INCLUDE (   [PaymentEntryId]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Data Filegroup 1]

这是我使用相等运算符 (= 0) 时估计的执行计划的一部分: 预计执行计划

有人可以解释为什么在这种情况下(或可能在许多情况下),不等式运算符似乎比等式运算符快吗?

4

1 回答 1

1

我不知道为什么,但我无法发表评论,只有答案,所以如果这对你不起作用,请忽略。

使用“WHERE ToIgnore = 0”创建非聚集索引应该可以解决此问题。

ToIgnore=1 vs ToIgnore=0 的记录数是多少?我的猜测是 ToIngore=1 的记录数量远大于设置为 0 的记录。

我记得不久前一个 Oracle/SQL DBA 告诉我,位列不需要索引,因为 Microsoft 已经为您处理好了,这可以解释您的问题。但是,我找不到任何支持它的东西,这可能是 Oracle 的问题,他们认为 MS 也必须这样做。

于 2012-11-27T14:44:12.450 回答