For SQL Server, there are many factors that contribute to the final execution plan. At a basic level, statistics play a very large role, but they are based on data, but not always on all data. Statistics are also not always relevant. When creating or restoring an index, statistics should be based on a FULL / 100% sample of data. However, the sampling rate for automatic statistics updates is much lower than 100%, so you can try a range that is actually not representative of most of the data. The estimated number of rows for the operation also plays a role, which can be based on the number of rows in the table or statistics of the filtered operation. Thus, outdated (or incomplete) statistics can lead the optimizer to choose a less optimal plan, since several rows in the table can make it completely ignore indexes (which can be more efficient).
As mentioned in another answer, the more unique (i.e. selective) the data, the more useful the index will be. But keep in mind that the only guaranteed column for statistics is the leading (or “leftmost” or “first”) index column. SQL Server may not collect statistics for other columns, even some of them are not included in any indexes, but only if AutoCreateStatistics DB is set (and it is by default).
In addition, having foreign keys can help the optimizer when these fields are in the query.
But one area not addressed in the question is the question of the request itself. A query that has slightly changed but still returns the same results may have a fundamentally different execution plan. It is also possible to terminate the use of the Index using:
LIKE '%' + field
or wrapping a field in a function, for example:
WHERE DATEADD(DAY, -1, field) < GETDATE()
Now keep in mind that read operations (ideally) are faster with indexes, but DML operations (INSERT, UPDATE and DELETE) are slower (with lots of CPU and disk I / O) since indexes need to be supported.
Finally, it is not always necessary to rely on “estimated” CPU values, etc. for value. The best test:
SET STATISTICS IO ON run query SET STATISTICS IO OFF
and focus on "logical readings." If you reduce logical reads, you must improve performance.
In the end, you will need a dataset that comes close to what you have in Production in order to configure the setting for both the indexes and the queries themselves.