Мне нужно сделать XML-файлы для таблицы, которая содержит более 300 тыс. Записей.
Код завершается за 3 ~ 4 секунды (это приемлемо?).
Добавьте к этому извлечение данных из MySQL, для завершения которого требуется ~ 32 с (это приемлемо?):
SELECT `id`, `join_at`
FROM girls g
WHERE g.del_flg = 0
ORDER BY g.join_at, g.id ASC
Если я выполню этот одиночный запрос со стороны navicat mysql, он все равно займет около 20 секунд.
Сначала запрос выбора не работал из-за ошибки «исчерпана память» (php.ini — memory_limit = 128M)
После этого я изменился memory_limit
до -1. Но я вижу, что многие люди говорят, что это плохо, чтобы изменить memory_limit
в -1
Так как оптимизировать select
запрос для 300к + записей в случае:
используя только PHP, SQL, код DOMDocument
Используйте параметры из # 1 в сочетании с индексированным столбцом в базе данных
все остальное, что вы знаете …
public function getInfo() {
MySQL::connect();
try {
$select = 'SELECT `id`, `join_at`';
$sql = ' FROM girls g';
$sql .= ' WHERE g.del_flg = 0';
$sql .= ' ORDER BY g.join_at, g.id ASC';
$sql = sprintf($sql, $this->table);
MySQL::$sth = MySQL::$pdo->prepare($select . $sql);
MySQL::$sth->execute();
while($rows = MySQL::$sth->fetch(\PDO::FETCH_ASSOC)) {
$values[] = array('id' => $rows['id'], 'join_at' => $rows['join_at']);
}
// $rows = MySQL::$sth->fetchAll(\PDO::FETCH_ASSOC);
} catch (\PDOException $e) {
return null;
}
return $values;
}
я узнал что ORDER BY g.join_at, g.id ASC
часть влияет на время исполнения. Когда я удаляю его и использую вместо него PHP для сортировки, время выполнения уменьшается с ~ 50 с до ~ 5 с.
Еще одна вещь, что если я установлю memory_limit
до 128M это приводит к ошибке «исчерпана память» (512M будет работать). Есть ли другое решение для этой проблемы?
Вот индексы, которые у меня есть на столе:
Сортировка лучше выполняется на стороне базы данных. Но вам нужно определить правильные индексы. order by
дорого в вашем случае. Хотя у вас есть индекс на del_flg
что может помешать сканированию таблицы, невозможно получить желаемый порядок вывода.
Поэтому я бы предложил изменить индекс del_flg
Вы должны включить больше полей:
DROP INDEX del_flg ON girls;
CREATE INDEX del_flg ON girls (del_flg, join_at, id);
Если это не улучшает время выполнения, то создайте индекс, который не включает del_flag
:
CREATE INDEX join_at ON girls (join_at, id);
Других решений пока нет …