Вложенный цикл while для получения данных DB. Времени в случайные моменты времени из-за версии PHP. Любой способ сделать это более эффективно?


Поэтому сегодня я вперемежку скрипт, который будет получать данные из базы данных из разных таблиц и все такое. Я хотел просто использовать простой МФС без отдыха, но я не мог сделать это возможным. Код я разместил это пойдет, но рандомно раз при тестировании, и я боюсь, как это будет работать в условиях стресса. Есть ли способ улучшить этот код, чтобы остановить тайм-ауту?

<?php
    $getConference = sprintf("SELECT DISTINCT confName, tableName FROM conferences WHERE enabled='1' ORDER BY id DESC");
    $catConference = mysql_query($getConference);
    while($conference = mysql_fetch_array($catConference)) {
        echo "<h2 class=\"expand\">".$conference['confName']."</h2>
                <ul class=\"collapse\">";
        $getExistingEvent = sprintf("SELECT DISTINCT event FROM " . $conference['tableName']);
        $catExistingEvent = mysql_query($getExistingEvent);
        while($existingevent = mysql_fetch_array($catExistingEvent)) {
            $getCat = sprintf("SELECT * FROM event WHERE id='".$existingevent['event']."'");
            $catResult = mysql_query($getCat);
            while($row = mysql_fetch_array($catResult)) {
                $getWinner = sprintf("SELECT place, name, event FROM 2012rlc WHERE event='".$row['id']."' ORDER BY place");
                $catWinner = mysql_query($getWinner);
                echo "
                    <li>
                        <h2 class=\"expand\">".$row['eventName']."</h2>
                        <ul class=\"collapse\">
                    ";

                while($winner = mysql_fetch_array($catWinner)) {
                    echo "<li>".$winner['place']. " ".$winner['name']."</li>";
                }
                echo "</ul></li>";
            }
        }
        echo "</ul>";
    }
    mysql_free_result($catResult);
    mysql_free_result($catWinner);
    mysql_free_result($catExistingEvent);
    mysql_free_result($catConference);
?>

Некоторые спрашивают для схемы базы данных, который я включил ниже:

CREATE TABLE `2012rlc` (
    `id` int(11) unsigned NOT NULL auto_increment,
    `place` varchar(4) default '',
    `name` varchar(255) default NULL,
    `event` int(5) default NULL,
    PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=52 DEFAULT CHARSET=latin1;

CREATE TABLE `conferences` (
    `id` int(11) unsigned NOT NULL auto_increment,
    `confName` varchar(255) default NULL,
    `tableName` varchar(50) default NULL,
    `enabled` tinyint(1) default '0',
    PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;


CREATE TABLE `event` (
    `id` int(11) unsigned NOT NULL auto_increment,
    `eventName` varchar(255) default NULL,
    `teamEvent` tinyint(1) default '0',
    PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=47 DEFAULT CHARSET=latin1;

Вывод команды EXPLAIN в MySQL:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  conferences ALL NULL    NULL    NULL    NULL    4   Using where; Using temporary; Using filesort


1333
3
задан 17 декабря 2011 в 03:12 Источник Поделиться
Комментарии
1 ответ

Прежде всего, вы таблицы имеют индексы? При выполнении запросов с объяснить на MySQL консоли (например объяснять выбор различных confName, имятаблицы из конференций, где включен='1' заказа по ID по убыванию), оно показывает, что он использует индексы?


Я не уверен, что это реальная проблема производительности или нет, но нынешняя mysql_free_result звонки не освобождает все ресурсы, только последний, потому что код выполняется много запросов в циклах. Вы должны поместить эти звонки сразу после последнего использования ресурса, например:

while (...) {
...
while($winner = mysql_fetch_array($catWinner)) {
echo "<li>".$winner['place']. " ".$winner['name']."</li>";
}
// free $catWinner at the end of every iteration
mysql_free_result($catWinner);
}


Я не думаю, что (как правило) хороший дизайн, чтобы создать отдельные таблицы для (наверное) один и тот же тип записей. Вместо того чтобы создавать отдельные таблицы для каждой конференции, можно создать только одну таблицу. Он должен иметь conferenceId атрибута, а также на конференциях таблица должна иметь conferenceId тоже (вместо таблицы атрибутов). (Не забывайте заграничного ключи.)

Если я прав, то это conferenceId может быть в случае таблицы и вам не нужны отдельные столы на всех. (Не стесняйтесь размещать ваши схемы базы данных. Может быть стоит новый вопрос.)


С помощью функции sprintf не имеет никакого смысла здесь и в подобных звонков:

$getExistingEvent = sprintf("SELECT DISTINCT event FROM " . $conference['tableName']);

Это так же, как

$getExistingEvent = "SELECT DISTINCT event FROM " . $conference['tableName'];

Или это может быть

$getExistingEvent = sprintf("SELECT DISTINCT event FROM %s", $conference['tableName']);

где ом означает в том числе/форматирование.


Редактировать:

Я хотел создать следующие индексы:

ALTER TABLE `conferences` ADD INDEX `enabled`(`enabled`);
ALTER TABLE `2012rlc` ADD INDEX `event_id`(`event`);

Я надеюсь, что это помогает.

1
ответ дан 17 декабря 2011 в 03:12 Источник Поделиться