получить n записей одновременно из временной таблицы - PullRequest
2 голосов
/ 18 июня 2010

У меня есть временная таблица с около 1 миллиона записей. Временная таблица хранит результат запроса большего размера. Я хочу обработать эти записи 1000, например, за один раз. Каков наилучший способ настроить запросы так, чтобы я получал первые 1000 строк, затем следующие 1000 и т. Д.? Они не упорядочены по своей сути, но временная таблица содержит только один столбец с идентификатором, поэтому я могу заказать его при необходимости. Я думал о создании дополнительного столбца с временной таблицей для нумерации всех строк, что-то вроде:

CREATE TEMP TABLE tmptmp AS
SELECT ##autonumber somehow##, id
FROM .... --complicated query

тогда я могу сделать:

SELECT * FROM tmptmp WHERE autonumber>=0 AND autonumber < 1000

и т.д ... как бы я на самом деле это сделал? Или есть лучший способ? Я использую Python и PostgreSQL.

Ответы [ 2 ]

4 голосов
/ 18 июня 2010

Используйте курсор и извлекайте нужные вам строки.Смещение ... предел станет медленным, когда у вас много записей, курсор будет работать намного лучше.

http://www.postgresql.org/docs/8.4/interactive/sql-fetch.html

1 голос
/ 18 июня 2010

Возможно, вы могли бы использовать что-то подобное (мы используем это при пакетном обновлении таблицы с +20 миллионами строк и не хотим перегружать репликацию).

import sys
import psycopg2
from datetime import datetime

firstid = 0
splitsize = 50 # Size of each batch


# Complicated query
query_complex = """
    CREATE TEMP TABLE tmptmp AS
    SELECT * FROM schema.massive_table
"""
# Query to be run at intervals
query = """
    SELECT * FROM tmptmp WHERE id BETWEEN %(startid)s AND %(endid)s
"""

conn = psycopg2.connect("dbname=database_name user=postgres")
curs = conn.cursor()
# Run complicated query
curs.execute(query_complex)
# Get highest id
curs.execute("SELECT max(id) FROM tmptmp")
maxid = curs.fetchall()[0][0]
print "Max id: %s" % maxid

for startid in range(firstid, maxid, splitsize):
    endid = startid + splitsize - 1
    print "%s: Running query on range %s to %s" % (datetime.now(), startid, endid)
    curs.execute(query, {'startid':startid, 'endid':endid})
    print "%s: Affected rows: %s. Total completed: %s%%" % (datetime.now(), curs.rowcount, round((endid * 100) / maxid, 3))

print "Done."

Вывод, следующий:

Max id: 308
2010-06-18 11:59:11.271000: Running query on range 0 to 49
2010-06-18 11:59:11.271000: Affected rows: 49. Total completed: 15.0%
2010-06-18 11:59:11.271000: Running query on range 50 to 99
2010-06-18 11:59:11.271000: Affected rows: 50. Total completed: 32.0%
2010-06-18 11:59:11.271000: Running query on range 100 to 149
2010-06-18 11:59:11.271000: Affected rows: 50. Total completed: 48.0%
2010-06-18 11:59:11.271000: Running query on range 150 to 199
2010-06-18 11:59:11.271000: Affected rows: 49. Total completed: 64.0%
2010-06-18 11:59:11.271000: Running query on range 200 to 249
2010-06-18 11:59:11.271000: Affected rows: 42. Total completed: 80.0%
2010-06-18 11:59:11.271000: Running query on range 250 to 299
2010-06-18 11:59:11.318000: Affected rows: 3. Total completed: 97.0%
2010-06-18 11:59:11.318000: Running query on range 300 to 349
2010-06-18 11:59:11.318000: Affected rows: 1. Total completed: 113.0%
Done.

// Джон

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...