-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();
}

しかし、このテーブルはすでに 1,500 万行あり、日付による一時的な並べ替えには時間がかかります。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 句から ORDER 句を削除したことに注意してください。私はこの方法で最初の 1000 行をキャプチャし、それらを逆方向に印刷するだけだと信じています。おそらく、LIMIT 句を削除してから、1000 行に達したときに手動でカーソルを閉じるとうまくいくでしょうか? または、DB エンジンを過負荷にしますか?

4

2 に答える 2

2

この場合、私が通常行っていること:

1, SELECT MIN( id) を min_id FROM table WHERE 条件として

2, SELECT MAX( id) を max_id FROM table WHERE 条件として

3, SELECT * FROM テーブル 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 に答える