We have events insert into a table – a start event and an end event. Related events have the same internal_id number, and are inserted within a 90 second window. We frequently do a self-join on the table:
create table mytable (id bigint identity, internal_id bigint,
internal_date datetime, event_number int, field_a varchar(50))
select * from mytable a inner join mytable b on a.internal_id = b.internal_id
and a.event_number = 1 and b.event_number = 2
However, we can have millions of linked events each day. Our clustered key is the internal_date, so we can filter down to a partition level, but the performance can still be mediocre:
and a.internal_date >='20120807' and a.internal_date < '20120808'
and b.internal_date >='20120807' and b.internal_date < '20120808'
Is there a SARGable way to narrow it down further?
Adding this doesn’t work – non-SARGable:
and a.internal_date <= b.internal_date +.001 --about 90 seconds
and a.internal_date > b.internal_date - .001 --make sure they're within the window
This isn’t for a point query, so doing one-offs doesn’t help – we’re searching for thousands of records and need event details from the start event and the end event.
Thanks!
With this index your query will be much cheaper:
The index allows you to seek on
event_numberrather than doing a clustered index scan, as well as enables you to do a merge join oninternal_idrather than a hash join. The uniqueness constraint makes merge join even cheaper by eliminating possibility of many-to-many join.See this for a more detailed explanation of merge join.