I have created a database using DataContext.CreateDatabase and inserted records in it.
There are a lot of records in it so I want to find a record by it's id in the fastest way.
firstly I tried:
foreach (var currentRecord in _context.Cities)
{
if (currentRecord.ID == recordIdToFind)
return currentRecord;
}
but it was very slow so I changed it to:
var recordToReturn = from r in _context.Cities
where r.ID == recordIdToFind
select r;
return recordToReturn.FirstOrDefault();
and got it faster.
is there is a better-faster way?
Whatever you are searching on (regularly) needs to have an index defined on it in the database for optimal speed. Note that some columns and certain kinds of searches don't index well (large text fields or "contains" searches, for example) and a different kind of index (full text) may be needed for those. In your case, it appears that you are using the primary key, which should have a clustered index on it.
Once you have the index(es) defined, you then want to perform queries that take advantage of the index. The first query does a full table scan, loading all the results into memory and then iterating through them in code. You haven't given the database any chance to help you speed up the query and are transferring a lot more data than you need. Your second query allows the database to use the index to find just the row that you are interested in by adding a where clause that specifies an indexed column. If done in isolation (i.e., you're only looking up this one row, not every row in order), then it's optimal. It does an index lookup for the row and then transfers just that row to your application.
If it is, in fact, the primary key, then you might improve on the readability, though not the performance, by using
SingleOrDefault
as there can only be one row with that key in the table. Enforcing the singleness of the query will also help detect potential errors, though not in the context of the primary key, if you have a column that you expect to be unique but isn't. In that caseSingleOrDefault
will throw an exception if more than one result is found, whereasFirstOrDefault
will simply choose the first one in the set without giving you any information about the inconsistency.