首页 文章

PHP PDO在没有ORDER的MySQL中向后搜索

提问于
浏览
-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();
}

但是这个表已经是15M行了,按日期的临时SORT是永远的 . 将其作为unix时间戳整数进行转换也没有多大帮助 .

我已经尝试使用MongoDB执行此任务,并在DATE构建具有相反顺序的索引,但没有任何排序:

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

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

根据MySQL documentation

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行时手动关闭光标会起作用? ¿或者我会超载数据库引擎吗?

2 回答

  • 1

    加速查询至少有两个技巧 .

    • 添加一些使用索引的条件,但减少了要排序的行数 . 比如说,限制一些确保超出范围的日期 .

    • 创建一个反向索引 - 非常unix时间戳,但是一个否定的时间戳,前面是 - . 这样,您将按数据获得索引,但顺序相反 . 不要忘记将此字段设置为signed int类型 .

  • 2

    在这种情况下我通常做的事情:

    1,SELECT MIN( id )作为min_id FROM表WHERE条件

    2,SELECT MAX( id )作为max_id FROM表WHERE条件

    3,SELECT * FROM表WHERE id > = min_id AND id <= max_id AND条件ORDER BY id DESC LIMIT 1000

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

相关问题