Идеальный способ запросить миллион записей - это использовать IQueryable<T>
, чтобы убедиться, что вы фактически не выполняете запрос к базе данных, пока вам не понадобятся фактические данные.Я очень сомневаюсь, что вам нужен миллион записей одновременно.
Причина, по которой он заблокирован, заключается в том, что вы просите сервер MySQL извлечь эти миллионы записей из базы данных, затем отсортировать их по EMPLOYEE_ID
, а затемдля вашей программы, чтобы вернуть это вам.Итак, я полагаю, что взаимоблокировки происходят из вашей программы, ожидая ее завершения, и из-за того, что ваша программа считывает это в память.Проблемы с MySQL, вероятно, связаны с проблемами тайм-аута.
Причина, по которой раздел var data
работает быстро, заключается в том, что вы на самом деле еще ничего не сделали, вы только что создали запрос.когда вы вызываете ToList()
, тогда выполняется весь SQL и чтение SQL.Это то, что известно как «Ленивая загрузка».
Я бы предложил попробовать это следующим образом:
var data = from employees in dataContext.employee_table
.Include("employee_type")
.Include("employee_status")
orderby employees.EMPLOYEE_ID descending
select employees;
Тогда, когда вам действительно понадобится что-то из списка, просто наберите
data.Where(/* your filter expression */).ToList()
Так что, если вам нужен сотрудник с ID 10.
var employee = data.Where(e => e.ID == 10).ToList();
Или если вам нужны все сотрудники, фамилии которых начинаются с S (я не знаю, есть ли в вашей таблице столбец с фамилией, простопример).
var employees = data.Where(e => e.LastName.StartsWith("s")).ToList();
Или, если вы хотите просмотреть всех сотрудников порциями по 100
var employees = data.Skip(page * 100).Take(100).ToList();
Если вы хотите еще больше отложить вызовы из базы данных, вы можетене звоните ToList()
, а просто используйте итератор, когда вам это нужно.Допустим, вы хотите сложить все зарплаты людей с именами, начинающимися с A
var salaries = data.Where(s => s.LastName.StartsWith("A"))
foreach(var employee in salaries)
{
salaryTotal += employee.Salary;
}
. Это только сделало бы запрос, который выглядел бы как
Select Salary From EmployeeTable Where ID = @ID
* 1032.* В результате получается очень быстрый запрос, который получает информацию только тогда, когда вам это нужно, и только ту информацию, которая вам нужна.
Если по какой-то безумной причине вы захотите запросить все миллионы записей для базы данных.Игнорируя тот факт, что это израсходует огромное количество системных ресурсов, я предложил бы делать это порциями, вам, вероятно, придется поиграться с размером порции, чтобы получить лучшую производительность.
Общая идея заключается в том, чтобывыполнять меньшие запросы, чтобы избежать проблем с тайм-аутом из базы данных.
int ChunkSize = 100; //for example purposes
HashSet<Employee> Employees - new HashSet<Employee>;
//Assuming it's exactly 1 Million records
int RecordsToGet = 1000000;
for(record = 0; record <= RecordsToGet; record += ChunkSize)
{
dataContext.EmployeeTable.Skip(record).Take(ChunkSize).ForEach(e => HashSet.Add(e));
}
Я решил использовать HashSet<T>
, поскольку они предназначены для больших наборов данных, но я не знаю, как будет выглядеть производительность1 000 000 объектов.