如何优化 select 300.000 行的 MySQL 代码 +

How to optimize MySQLl code that select for 300.000 rows +

我需要为包含 300k+ 条记录的 table 创建 XML 个文件。

代码大约需要 3~4 秒才能完成(这是 acceptable 吗?)。

再加上 MySQL 的数据检索,大约需要 32 秒才能完成(这是接受 table 吗?):

查询

SELECT `id`, `join_at` 
FROM girls g 
WHERE g.del_flg = 0 
ORDER BY g.join_at, g.id ASC

如果我 运行 来自 navicat mysql 的这个单一查询它仍然需要大约 20 秒。

我尝试了什么:

  1. 起初,select查询没有成功,因为“内存耗尽”错误(php.ini - memory_limit = 128M)

  2. 之后我将memory_limit改为-1。但是我看到很多人说把 memory_limit 改成 -1

    不好

那么如何针对 300k+ 记录优化 select 查询:

  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 设置为 128M,则会导致“内存耗尽”错误(512M 可以)。这个问题还有其他解决方案吗?

这是我目前在 table:

上的索引

排序最好在数据库端完成。但是您需要定义适当的索引。 order by 在您的情况下很昂贵。尽管您在 del_flg 上有一个可以阻止 table 扫描的索引,但它无法产生所需的输出顺序。

所以我建议更改索引 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);