2

次のタイプのデータがあります。

データは「フレーム」に分割され、各フレームには開始と停止の「gpstime」があります。各フレーム内には、「gpstime」値を持つ一連のポイントがあります。

frame_name、start_gps、stop_gps、...を持つフレーム モデルがあります。

gpstime 値のリストがあり、それぞれに対応する frame_name を見つけたいとしましょう。

私はただループをすることができました...

framenames = [frames.objects.filter(start_gps__lte=gpstime[idx],stop_gps__gte=gpstime[idx]).values_list('frame_name',flat=True) for idx in range(len(gpstime))]

これにより、gpstime ごとに 1 つずつ、「frame_name」のリストが表示されます。これが私が欲しいものです。ただし、これは非常に遅いです。

私が知りたいこと: このルックアップを実行して、リストを反復処理するよりも効率的な各 gpstime のフレーム名を取得するより良い方法はありますか? このリストは非常に大きくなる可能性があります。

ありがとう!

編集:フレームモデル

class frames(models.Model):
    frame_id = models.AutoField(primary_key=True)
    frame_name = models.CharField(max_length=20)
    start_gps = models.FloatField()
    stop_gps = models.FloatField()

    def __unicode__(self):
        return "%s"%(self.frame_name)
4

3 に答える 3

0

フレーム テーブルは非常に大きいですが、この場合に検索されるフレームを 50 未満に下げる別の値があります。実際にはパターンはなく、各フレームは前の停止と同じ gpstime で開始します。

検索フレーム数をどのように 50 に減らしたのかよくわかりませんが、たとえばgpstime50 だけで 10,000 個の値を検索している場合frames、これらの 50 フレームを RAM にロードし、検索を実行するのがおそらく最も簡単です。 Python、foobarbecueの答えに似たものを使用しています。

gpstimeただし、たとえば 10,000,000 を持つテーブル全体で 10 個の値を検索する場合、frames10,000,000 フレームすべてを RAM にロードしたくない場合があります。

次のインデックスを追加することで、DBに同様のことをさせることができます...

ALTER TABLE myapp_frames ADD UNIQUE KEY my_key (start_gps, stop_gps, frame_name);

...次に、このようなクエリを使用して...

(SELECT frame_name FROM myapp_frames
        WHERE 2.5 BETWEEN start_gps AND stop_gps LIMIT 1)
    UNION ALL
(SELECT frame_name FROM myapp_frames
        WHERE 4.5 BETWEEN start_gps AND stop_gps LIMIT 1) 
    UNION ALL
(SELECT frame_name FROM myapp_frames
        WHERE 7.5 BETWEEN start_gps AND stop_gps LIMIT 1);

...戻ります...

+------------+
| frame_name |
+------------+
| Frame 2    |
| Frame 4    |
| Frame 7    |
+------------+

...そして、どのEXPLAINショーのために...

+----+--------------+--------------+-------+---------------+--------+---------+------+------+--------------------------+
| id | select_type  | table        | type  | possible_keys | key    | key_len | ref  | rows | Extra                    |
+----+--------------+--------------+-------+---------------+--------+---------+------+------+--------------------------+
|  1 | PRIMARY      | myapp_frames | range | my_key        | my_key | 8       | NULL |    3 | Using where; Using index |
|  2 | UNION        | myapp_frames | range | my_key        | my_key | 8       | NULL |    5 | Using where; Using index |
|  3 | UNION        | myapp_frames | range | my_key        | my_key | 8       | NULL |    8 | Using where; Using index |
| NULL | UNION RESULT | <union1,2,3> | ALL   | NULL          | NULL   | NULL    | NULL | NULL |                          |
+----+--------------+--------------+-------+---------------+--------+---------+------+------+--------------------------+

...そのため、そのインデックスにヒットする 1 つのクエリですべてのルックアップを実行でき、インデックスは RAM にキャッシュする必要があります。

于 2013-06-12T14:09:29.543 に答える