-1

我有一个大屁股 mysql 表,我需要获取匹配条件的最近 1000 行。显而易见的方法是

try {
    $stmt = $dbh->prepare("SELECT id, date, field1, field2 
    FROM big_ass_table
    WHERE field1 >= 1000 and field2 <=4550
    ORDER BY date DESC LIMIT 0,1000");
    $stmt->execute();
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        print_r($row);
    }
    $stmt = null;
} catch (PDOException $e) {
    print $e->getMessage();
}

但是这个表已经有 1500 万行了,并且临时的按日期排序需要永远。将其转换为 unix 时间戳整数也无济于事。

我已经尝试使用 MongoDB 来完成这项任务,并在 DATE 上建立一个反向顺序的索引,无需任何排序即可解决问题:

$cursor=$mongodb->big_ass_table
->find(array('$and'=>array($conditions)))
->hint( "date_-1" )
->limit(1000);

有很多理由继续使用 mysql 来完成这项任务(尽管我越来越喜欢 MongoDB)所以我希望 mysql 有一种方法,特别是 PDO Mysql,可以向后搜索。

根据MySQL 文档

index_col_name 规范可以以 ASC 或 DESC 结尾。这些关键字被允许用于指定升序或降序索引值存储的未来扩展。目前,它们被解析但被忽略;索引值始终按升序存储。

所以我在这里处于死胡同。然后我求助于PDO。是否有可能使它与类似的东西一起工作

try {
    $stmt = $dbh->prepare("SELECT id, date, field1, field2 
    FROM big_ass_table
    WHERE field1 >= 1000 and field2 <=4550
    LIMIT 0,1000", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
    $stmt->execute();
    $row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_LAST);
    do {
      print_r($row);
    } while ($row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_PRIOR));
    $stmt = null;
}   catch (PDOException $e) {
    print $e->getMessage();
}

注意我已经从最后一个中删除了 ORDER 子句。我相信这样我仍然会捕获前 1000 行,然后将它们向后打印,这不是我需要做的。¿也许如果我删除 LIMIT 子句然后在达到 1000 行时手动关闭游标会起作用吗?¿ 或者我是否会使数据库引擎过载?

4

2 回答 2

2

在这种情况下我通常会做什么:

1、SELECT MIN( id) as min_id FROM table WHERE 条件

2、SELECT MAX( id) as max_id FROM table WHERE 条件

3、SELECT * FROM table WHERE id>= min_idAND id<= max_idAND 条件 ORDER BY id DESC LIMIT 1000

这样,您只需对匹配列表进行排序。当然,如果您的匹配列表很大,那么您就有问题了。在这种情况下,请查看对表进行分区

于 2013-08-16T13:36:54.803 回答
1

至少有 2 个技巧可以加快查询速度。

  1. 添加一些使用索引但会减少要排序的行数的条件。比如说,限制在某个保证超出范围的特定日期。
  2. 创建一个反向索引 - 非常 unix 时间戳,但是一个否定的,-在前面。这样,您将按数据索引,但顺序相反。不要忘记将此字段设为signed int 类型。
于 2013-08-16T13:32:54.677 回答