13
Reading about indexes I recently came across the term "selectivity". Some places said more selective fields should come first on the index, others say no or that it depends.
I have the following table tbMovimentoConta
abbreviation (mcon
) with 5 million records, and the following columns that will be used in where
- mcon_dataExclusion (99% of the records have the value
null
) because data cannot be deleted withdelete from
- con_codigo_fk (there are 5 distinct values(1,2,3,4,5) divided for the 5 million records)
- mcon_data (1825 distinct dates for the 5 million records)
I have the following query that is generated by the Entity Framework:
exec sp_executesql N'SELECT
[Project1].[C2] AS [C1],
[Project1].[mcon_codigo_pk] AS [mcon_codigo_pk],
[Project1].[mcon_data] AS [mcon_data],
[Project1].[mcon_obs] AS [mcon_obs],
[Project1].[mcon_valor] AS [mcon_valor],
[Project1].[mcon_tipo] AS [mcon_tipo]
FROM ( SELECT
convert (datetime2, convert(varchar(255), [Extent1].[mcon_data], 102) , 102) AS [C1],
[Extent1].[mcon_codigo_pk] AS [mcon_codigo_pk],
[Extent1].[mcon_data] AS [mcon_data],
[Extent1].[mcon_valor] AS [mcon_valor],
[Extent1].[mcon_tipo] AS [mcon_tipo],
[Extent1].[mcon_obs] AS [mcon_obs],
1 AS [C2]
FROM [dbo].[tbMovimentoConta] AS [Extent1]
WHERE ([Extent1].[mcon_data] >= @p__linq__0) AND ([Extent1].[mcon_data] <= @p__linq__1) AND ([Extent1].[con_codigo_fk] = @p__linq__2) AND ([Extent1].[mcon_dataExclusao] IS NULL)
) AS [Project1]
ORDER BY [Project1].[C1] ASC, [Project1].[mcon_codigo_pk] ASC
OFFSET 764225 ROWS FETCH NEXT 11 ROWS ONLY ',N'@p__linq__0 datetime2(7),@p__linq__1 datetime2(7),@p__linq__2 bigint',@p__linq__0='2012-01-01 00:00:00',@p__linq__1='2013-01-01 23:59:59',@p__linq__2=1
I tested with two index settings
Index 1
CREATE NONCLUSTERED INDEX [ix_consulta_movimento] ON [dbo].[tbMovimentoConta]
(
[mcon_dataExclusao] ASC,
[con_codigo_fk] ASC,
[mcon_data] ASC
)
INCLUDE (
[mcon_dataInclusao],
[mcon_codigo_pk],
[mcon_valor],
[mcon_tipo],
[mcon_obs]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
Index 2
CREATE NONCLUSTERED INDEX [ix_consulta_movimento] ON [dbo].[tbMovimentoConta]
(
[mcon_data] ASC,
[con_codigo_fk] ASC,
[mcon_dataExclusao] ASC
)
INCLUDE (
[mcon_dataInclusao],
[mcon_codigo_pk],
[mcon_valor],
[mcon_tipo],
[mcon_obs]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
In the tests I did, the index 1 was faster, but I thought the 2 would be faster. Could someone explain to me why the index 1 is faster, or if there’s something wrong with it, so the 2 would have to be faster.
Editing
Doing more tests here, it seems that the index 2 is faster even. Anyway I’m doubt. I need to have a clear understanding of how to sort these columns in the index.
It depends on what you need. If you put the
ID
At first you’ll have great selectivity, but if you want a group of information between dates, it doesn’t help at all. If you do it blindly you will end up creating dozens of indexes, most without real need and may have performance loss elsewhere.– Maniero
I’ll edit the question. I took the trace query that the Entity Framework is generating, and I’ll complete the missing index includes Columns.
– user26552
Perhaps an analysis of the consultation implementation plan can help you understand. The plan includes JOIN and WHERE strategies that can provide better answers than just the question of choosing the indexes.
– Pagotti
I did that, actually he who suggested the index 1, I created the index two.
– user26552
Those interested in understanding more about indexes have 3 books that are FREE and good. http://www.red-gate.com/library/sql-server-execution-plans-2nd-edition , http://www.red-gate.com/community/books/inside-sql-server-query-optimizer e https://www.simple-talk.com/books/sql-books/complete-showplan-operators/
– Ruberlei Cardoso
I put in this answer a command to check missing Indice, see if it helps, and also always analyze the query plan, remembering that every Indice created has an impact on Insert, update and delete. https://answall.com/questions/173358/howto improve a-performance-de-leitura-de-um-banco-dados-sql/173899#173899
– Dorathoto
Then shows the execution plan, only with it can be sure if the query ran more or less fast.
– Luiz Santos