Domanda

In regards to this specific query :

Don't expect to understand the data that is queried : it is irrelevant.

Just take a look at the WHERE clause :

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

Especially these two inequalities :

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

Note : ToIgnore is a bit column.

This query takes around 10 seconds to return about 1300 rows.

However, if I change these two lines to use the equality operator :

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

It takes forever to return anything.

It it helps, here are the indexes from each table :

Table DocumentEntry indexes :

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]

Table DocumentEntryValue indexes :

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]

Table DocumentEntryValueRate indexes :

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]

Table PaymentEntry indexes :

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]

Table PaymentEntryRate indexes :

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]

Here is a part of the estimated execution plan when I use the equality operators (= 0) : Estimated execution plan

Can someone explains why, in this case (or probably in many cases), the inequality operator seems faster than the equality operator ?

È stato utile?

Soluzione

I'm not sure why, but I'm unable to post comments, only answers so please ignore if this doesn't work for you.

Creating a nonclustered index with "WHERE ToIgnore = 0" should correct the issue.

What is the record count for records with ToIgnore=1 vs ToIgnore=0? My guess is the amount of records with ToIngore=1 is much larger than them being set to 0.

I remember a while back an Oracle/SQL DBA telling me that and index was not needed for bit columns because Microsoft took care of that for you, which would explain your problem. However, I'm unable to find anything to back it up and it might be something with Oracle and they assumed MS must do it as well.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top