Запрос в цикле, как я могу улучшить скорость этого? Два типа БД - PullRequest
1 голос
/ 21 июня 2011

редактировать Думаю, мне нужно добавить больше информации. Этот первый запрос - MySQL, последние два - PGSQL, и он расположен на отдельном сервере. Когда я отключаю второй запрос во второй части этого, он все еще так же медленно.

SELECT n.id, n.number, n.assigned, n.btn, n.status as stat, s.status 
FROM numbers n 
LEFT JOIN status s on n.status=s.id 
where number like '239333%'
LIMIT $start, $limit

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

В этом списке выводится цикл while в PHP.

В этом цикле while есть второе подключение к отдельному серверу (postgres) для дополнительных проверок этого числа, которое выполняется с помощью функции, поэтому в цикле у меня есть, например, $ mq = extension_checks ($ number) ; * +1010 *

$query = "SELECT count(baseinformation_directorynumber) as count FROM \"public\".\"meta_subscriber\" WHERE baseinformation_directorynumber = $number";
$result = pg_query($query) or die('Query failed: ' . pg_last_error());
$row = pg_fetch_assoc($result);
$did = "0";
if ($row['count'] == '0') {
    $query2 = "SELECT count(lastdirectorynumber) as count FROM \"public\".\"meta_pbx_directinwardcalling\" where firstdirectorynumber <= $number and $number <= lastdirectorynumber";
    $result2 = pg_query($query2) or die('Query failed: ' . pg_last_error());
    $row2 = pg_fetch_assoc($result2);
    if ($row2['count'] == '1') { 
        $did = $row2['count'];
        $row['count'] = "0";
    }

}

pg_free_result($result);

// Closing connection

$line = $row['count'];
$match = array('line' => $line, 'did' =>  $did);
return $match;

После этого я делаю еще пару проверок для отображения необходимой информации.

Проблема в том, что когда я добавил запрос Additional_checks, загрузка 50 элементов заняла около 30 секунд. Я спрашиваю (из-за недостатка знаний), как я могу увеличить скорость, чтобы это было немного более приемлемым.

Если это поможет, вот мой главный пока смотрите

while ($q->getrow()) {
$number = $q->field('number'); $assigned = $q->field('assigned'); $btn = $q->field('btn'); $id = $q->field('id'); $status = $q->field('status'); $stat = $q->field('stat');
$nc++; //Start Counter
$now = time(); 
$diff = $now - $time; 
if ($alternate == "1") {
    $color = "#EFEFEF";
    $alternate = "2";
} else {
    $color = "#DFDFDF";
    $alternate = "1";
}
$match = meta_query($q->field('number'));
if ($match['line'] == '1' and $match['did'] == '0') { 
    $numcolor = "green";
    $did = "";
} elseif ($match['did'] == '1' AND $match['line'] == '0') { 
    $did = "[DID]"; 
    $numcolor = "green";
} else {
    $did = "";
    if ((!$assigned) AND (!$btn) AND ($stat == '1' OR $stat == '4')) {
        $numcolor = "";
    } else {
        $numcolor = "red";
    }

}
//if ($numcolor = "red" AND $assigned == '' AND $btn == '' AND $stat == '1') {
//  $numcolor = "";
//}
//print_r($match);
if ($stat == '4') { $color = "C2FACB"; }
elseif ($stat == '2') { $color="FCFBEA"; }
// else {
$ajaxedits .= "EditInPlace.makeEditable({ id: 'btn:$id' });\n";
$ajaxedits .= "EditInPlace.makeEditable({ id: 'assigned:$id' });\n";
$ajaxedits .= "EditInPlace.makeEditable({
    id: 'status:$id',
    type: 'select',
    save_url: 'optionedit_eip.php',
    options: {
        1: 'Free',
        2: 'In use',
        3: 'Disconnected',
        4: 'Ported Out'
    }
});";
//}
//<span class="red" id="status:$id">Dark Green</span>
//
if (isset($right[admin])) {
     $clear = "<a href=\"index.php?a=clearrow&id=$id\"> (Clear)</a>";
}   
eval("\$list_numbers .= \"".addslashes($TI[5])."\";");
}
$q->free;

следующий

$match = meta_query($q->field('number'));

- это функция, к которой она обращается для выполнения дополнительных проверок postgres, перечисленных выше. Да, мой код ужасен, я все еще нуб. :)

Ответы [ 2 ]

2 голосов
/ 21 июня 2011

SQL-запросов внутри циклов можно избежать. Один из способов - собрать все $ числа в массиве php, а затем выполнить один запрос после цикла.

..WHERE baseinformation_directorynumber IN ($num1, $num2, ...);

Вы получите количество всех чисел за один раз. Это ускорит выполнение.

Я нашел сообщение в блоге, содержащее больше способов избежать sql в циклах. проверить артикул

2 голосов
/ 21 июня 2011

Посмотрите на использование JOIN на двух таблицах.Затем вы можете сравнить скорости, но в зависимости от количества строк у вас JOIN должно быть быстрее, чем два запроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...