So I have the following indexes on my table:
CREATE NONCLUSTERED INDEX [$5] ON [dbo].[Record Link]
(
[Company] ASC,
[Record ID] 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, FILLFACTOR = 80) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [$6] ON [dbo].[Record Link]
(
[Notify] ASC,
[Record ID] 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, FILLFACTOR = 80) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [$7] ON [dbo].[Record Link]
(
[Company] ASC,
[Type] ASC,
[Link ID] ASC,
[Record ID] 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, FILLFACTOR = 80) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [$8] ON [dbo].[Record Link]
(
[Company] ASC,
[Type] ASC,
[Record ID] 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, FILLFACTOR = 80) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [bain_test] ON [dbo].[Record Link]
(
[Record ID] ASC,
[Type] ASC,
[Company] 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, FILLFACTOR = 80) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [$4] ON [dbo].[Record Link]
(
[Notify] ASC,
[Company] ASC,
[Link ID] ASC,
[To User ID] 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, FILLFACTOR = 80) ON [PRIMARY]
GO
The Problem is that some of the indexes only get used some times. As an example look at this query and the Execution plan, you can see that it is executed within the EXISTS but it is not executed for the rest of the query. Both where clauses are identical.
Here is that queries statistics time and IO:
*SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
Table 'Record Link'. Scan count 1, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.*
*(1 row affected)*
*SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.*
*(1 row affected)*
*Table 'Record Link'. Scan count 1, logical reads 1017129, physical reads 0, read-ahead reads 0, lob logical reads 1, lob physical reads 0, lob read-ahead reads 0.*
*(1 row affected)*
*SQL Server Execution Times:
CPU time = 1969 ms, elapsed time = 1963 ms.*
I don't have the option of changing the query as it from an ERP system and I'm trying to optimize the speed.
And while we are here there are a few different variations for querying this table.
Here are another one that don't use the indexes at all.
With this one things are strange, so i first tried having an index that uses fields: Record ID, Company, this didn't work until I created a new index and made it: Company, Record ID.
I Did this yesterday and it was working, but this morning in the profiler its not using the index again.
SELECT TOP (1)
"timestamp","Link ID",
"Record ID",
"URL1",
"URL2",
"URL3",
"URL4",
"Description",
"Type",
DATALENGTH("Note"),
"Created",
"User ID",
"Company",
"Notify",
"To User ID"
FROM
"Live".dbo."Record Link" WITH(UPDLOCK)
WHERE
("Record ID"=@0 AND "Company"=@1)
ORDER BY
"Link ID" ASC
OPTION(OPTIMIZE FOR UNKNOWN)
With this one, i really just cant figure it out, i thought the index with company,notify,User ID would work:
SELECT TOP (@0)
"timestamp", "Link ID", "Record ID",
"URL1", "URL2", "URL3", "URL4",
"Description", "Type", DATALENGTH("Note"), "Created", "User ID",
"Company", "Notify", "To User ID"
FROM "Live_Replica".dbo."Record Link" WITH(READUNCOMMITTED)
WHERE ("Link ID">@1
AND (("Company"=@2 OR "Company"=@3)
AND "Notify"=@4
AND ("To User ID" COLLATE Latin1_General_100_CI_AI LIKE @5
OR "To User ID" COLLATE Latin1_General_100_CI_AI LIKE @6)))
ORDER BY "Link ID" ASC
OPTION(OPTIMIZE FOR UNKNOWN, FAST 50)
I Have tried googling for this issues but cant seem to find an answer at all. All indexes are rebuilt every night and i don't shrink the database at all so that the indexes don't get fragmented.