Добрый день!
У меня проблема с медленным выполнением моего PHP-скрипта. Я не уверен, что это правильный вопрос. Пожалуйста, потерпите меня.
Моя задача - создать веб-приложение для преобразования существующего файла SDF (SQL Server CE) в БД (файл SQlite). Я использую PHP.
База данных SQlite будет использоваться в мобильном приложении.
Вот шаги моего преобразования:
Мне пришлось бы повторить этот процесс, если бы пользователь выбрал несколько файлов.
Вот мой код для справки:
/**
* ARBalances
*/
$file_db->exec("CREATE TABLE IF NOT EXISTS ARBalances (
_id INTEGER PRIMARY KEY AUTOINCREMENT,
CustomerCode NVARCHAR(10),
BillingDate TEXT,
Balance DECIMAL(15,2),
SalesId NVARCHAR(30),
Amount DECIMAL(18,2),
Payment DECIMAL(18,2))");
/**
* Insert Data to db file. Select ARBalances from SDF file
*/
$sdf->execute("SELECT * FROM ARBalances");
$this->data_array = [
'customer_code' => NULL,
'billing_date' => NULL,
'balance' => NULL,
'sales_id' => NULL,
'amount' => NULL,
'payment' => NULL,
];
$ar_balances = [];
while (!$sdf->eof()) {
$ar_balances[$sdf->fieldvalue('SalesId')] = $this->data_array;
$ar_balances[$sdf->fieldvalue('SalesId')]['customer_code'] = $sdf->fieldvalue('CustomerCode');
$date = str_replace('/', '-', $sdf->fieldvalue('BillingDate'));
$date = new DateTime($date);
$billing_date = strtotime($date->format('Y-m-d H:i:s'));
$billing_date = (int)$billing_date * 1000;
$ar_balances[$sdf->fieldvalue('SalesId')]['billing_date'] = $billing_date;
$ar_balances[$sdf->fieldvalue('SalesId')]['balance'] = (float)$sdf->fieldvalue('Balance');
$ar_balances[$sdf->fieldvalue('SalesId')]['sales_id'] = (string)$sdf->fieldvalue('SalesId');
$ar_balances[$sdf->fieldvalue('SalesId')]['amount'] = (float)$sdf->fieldvalue('Amount');
$ar_balances[$sdf->fieldvalue('SalesId')]['payment'] = (float)$sdf->fieldvalue('Payment');
$sdf->movenext();
}
$insert = "INSERT INTO ARBalances(CustomerCode, BillingDate, Balance, SalesId, Amount, Payment)
VALUES (:customer_code, :billing_date, :balance, :sales_id, :amount, :payment)";
$stmt = $file_db->prepare($insert);
$stmt->bindParam(':customer_code', $customer_code);
$stmt->bindParam(':billing_date', $billing_date);
$stmt->bindParam(':balance', $balance);
$stmt->bindParam(':sales_id', $sales_id);
$stmt->bindParam(':amount', $amount);
$stmt->bindParam(':payment', $payment);
foreach ($ar_balances as $value) {
$customer_code = $value['customer_code'];
$billing_date = $value['billing_date'];
$balance = $value['balance'];
$sales_id = $value['sales_id'];
$amount = $value['amount'];
$payment = $value['payment'];
$stmt->execute();
}Этот код предназначен только для таблицы ARBalances. У меня в базе 38 таблиц. Некоторые таблицы содержат более 200 записей. Мое время выполнения занимает всего 5 минут на одно преобразование! Не знаю, нормально ли это, но думаю, что это займет слишком много времени.
Я думаю, что цикл while является причиной этой проблемы. Честно говоря, я не очень хорошо знаком с концепциями информатики или циклической оптимизацией.
Надеюсь, вы поможете мне оптимизировать мой код. Любое предложение будет очень признательно. Надеюсь, я ясно объяснил. Большое спасибо.
Привет @Shawn, Спасибо за предложения. Я уже подал заявку нет. 1. Немного улучшается. Я также прочитал ссылку, которую вы разместили. Я пытаюсь отредактировать свой код сейчас, просто быстрый вопрос, как я могу повторно использовать подготовку государственных деятелей для всех вставок? Я имею в виду, что у них разные имена столбцов и разное количество столбцов.






Вы хотите обернуть свои вставки sqlite как транзакцию. Вы можете найти дополнительную информацию по следующему адресу: http://www.sqlitetutorial.net/sqlite-php/transaction/
Некоторые предложения: 1. Отключите
AUTOINCREMENTот вашего первичного ключа; тормозит вставки и обычно не требуется. 2. Переместите подготовку оператора за пределы цикла и повторно используйте его для всех вставок. 3. Поместите все вставки в одну транзакцию. 4. Прочтите эта почта, чтобы узнать больше.