Как оптимизировать код MySQLl, который выбирается для 300 000 строк + - PullRequest
0 голосов
/ 02 февраля 2019

Мне нужно создать 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 с.

То, что я пытался:

  1. Сначала запрос на выборку не работал из-за ошибки «исчерпана память» (php.ini - memory_limit = 128M)

  2. После этого я изменил memory_limit на -1.Но я вижу, что многие люди говорят, что неправильно memory_limit превращать в -1

Так как оптимизировать запрос select для 300 000 записей + в случае:

  1. с использованием только PHP, sql, кода DOMDocument

  2. Используйте параметры из # 1 в сочетании с индексированным столбцом в базе данных

  3. все остальное, что вы знаете ...

PHP-код с SQL-запросом:

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 на 128 М, это приведет к «исчерпанию памяти»."ошибка (512M будет работать).Есть ли другое решение для этой проблемы?

Вот индексы, которые у меня сейчас есть в таблице:

Index

1 Ответ

0 голосов
/ 02 февраля 2019

Сортировка лучше выполняется на стороне базы данных.Но вам нужно определить правильные индексы.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);
...