Более эффективный способ хранения учетных данных MikroTik IP?

У меня был предыдущий вопрос о том, как сделать этот скрипт, и я нашел способ, но я не слишком уверен, должен ли я использовать этот метод. Другой пост доступен здесь.

Может ли кто-нибудь указать мне правильное направление, если есть более быстрый / эффективный способ запуска этого сценария, как мой предыдущий способ, который иногда выполнялся, иногда занимал более часа, чтобы закончить.

<?php
    //Require admin
    require_once("inc/admin.php");
    require_once ("../includes/routeros_api.class.php");

    //SET 
    $ip = "10.100.1.1";


    //Connect to MikroTik API
    $API = new RouterosAPI();
    $API->debug = $config['api']['debug'];
    if (!$API->connect($ip, $config['api']['username'], $config['api']['password'])) {
        echo "Could not connect to RouterOS API";
    } else {
        $API->write('/ip/accounting/snapshot/take',true);
        $READ = $API->read(false);
        $ARRAY = $API->parseResponse($READ);

$API->write('/ip/accounting/snapshot/print',true);
$READ = $API->read(false);
$ARRAY = $API->parseResponse($READ);

foreach($ARRAY as $ACCOUNTING) {
    $ip_src = $ACCOUNTING['src-address'];
    $ip_dst = $ACCOUNTING['dst-address'];
    $bytes = $ACCOUNTING['bytes'];

    //Check if ip in use UPLOAD
    $query = "SELECT id, ipv4 FROM services WHERE ipv4='$ip_src' AND deleted !='1'";
    $result = mysqli_query($conn, $query);
    $row = mysqli_fetch_array($result);

    if(mysqli_num_rows($result) > 0) {
        $service_id = $row['id'];
        //Update Download Traffic
        $check_if_exist_query = "SELECT * FROM traffic_counters WHERE service_id='$service_id' AND date=CURRENT_DATE()";
        $check_result = mysqli_query($conn, $check_if_exist_query);
        $check_num_rows = mysqli_num_rows($check_result);

        if($check_num_rows == 0) {
            $add_query = "INSERT INTO traffic_counters (service_id, upload_bytes, date) VALUES ('$service_id', '$bytes', CURRENT_DATE());";
            $add_result = mysqli_query($conn, $add_query);
        } else {
            $update_query = "UPDATE traffic_counters SET 
                                upload_bytes = upload_bytes + $bytes
                                WHERE service_id='$service_id' AND date=CURRENT_DATE();
                            ";
            $update_result = mysqli_query($conn, $update_query);
        }
    }

    //Check if ip in use DOWNLOAD
    $query = "SELECT id, ipv4 FROM services WHERE ipv4='$ip_dst' AND deleted !='1'";
    $result = mysqli_query($conn, $query);
    $row = mysqli_fetch_array($result);

    if(mysqli_num_rows($result) > 0) {
        $service_id = $row['id'];
        //Update Download Traffic
        $check_if_exist_query = "SELECT * FROM traffic_counters WHERE service_id='$service_id' AND date=CURRENT_DATE()";
        $check_result = mysqli_query($conn, $check_if_exist_query);
        $check_num_rows = mysqli_num_rows($check_result);

        if($check_num_rows == 0) {
            $add_query = "INSERT INTO traffic_counters (service_id, download_bytes, date) VALUES ('$service_id', '$bytes', CURRENT_DATE());";
            $add_result = mysqli_query($conn, $add_query);
        } else {
            $update_query = "UPDATE traffic_counters SET 
                                download_bytes = download_bytes + $bytes
                                WHERE service_id='$service_id' AND date=CURRENT_DATE();
                            ";
            $update_result = mysqli_query($conn, $update_query);
        }
    }
}
       $API->disconnect();
}
?>

1 ответ

1.) Вы можете начать с "упрощенных" запросов на вставку:

Просто установите переменную $INSERT_VALUES и делайте это в циклах

$INSERT_VALUES.=", ('$service_id', '$bytes', CURRENT_DATE())";

После цикла вы можете сделать только одну вставку (только один запрос) в базу данных:

$add_query = "INSERT INTO traffic_counters (service_id, upload_bytes, date) VALUES INSERT_VALUES"; 

2.) если у вас БОЛЬШОЕ количество строк, использование UPDATE - очень плохая идея, но при таком типе использования это невозможно решить. Вы можете попробовать позвонить на MySQL START TRANSACTION; и после всех обновлений звоните COMMIT;

3.) На большой базе данных SELECT ... WHERE ... Это медленнее, чем загрузка всех данных в массив php, а затем поиск нужной строки с помощью array_search или с помощью хорошего метода создания массива (например, $DATA[service_id]["colunm"]=$value)

Другие вопросы по тегам