PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

OFFSET đấu với ROW_NUMBER ()

Tôi đã tạo một bài kiểm tra so sánh OFFSET, con trỏ và ROW_NUMBER (). Ấn tượng của tôi về ROW_NUMBER (), rằng nó sẽ nhất quán về tốc độ bất kể bạn đang ở đâu trong tập kết quả, là chính xác. Tuy nhiên, tốc độ đó chậm hơn đáng kể so với OFFSET hoặc CURSOR, theo ấn tượng của tôi, là tốc độ khá giống nhau, cả hai đều giảm tốc độ càng về cuối kết quả mà bạn đạt được.

Kết quả:

offset(100,100): 0.016359
scroll(100,100): 0.018393
rownum(100,100): 15.535614

offset(100,480000): 1.761800
scroll(100,480000): 1.781913
rownum(100,480000): 15.158601

offset(100,999900): 3.670898
scroll(100,999900): 3.664517
rownum(100,999900): 14.581068

Tập lệnh thử nghiệm sử dụng sqlalchemy để thiết lập bảng và 1000000 hàng dữ liệu thử nghiệm. Sau đó, nó sử dụng con trỏ psycopg2 để thực thi từng câu lệnh SELECT và tìm nạp kết quả bằng ba phương pháp khác nhau.

from sqlalchemy import *

metadata = MetaData()
engine = create_engine('postgresql://scott:[email protected]/test', echo=True)

t1 = Table('t1', metadata,
    Column('id', Integer, primary_key=True),
    Column('d1', String(50)),
    Column('d2', String(50)),
    Column('d3', String(50)),
    Column('d4', String(50)),
    Column('d5', String(50))
)

if not engine.has_table('t1'):
    conn = engine.connect()
    t1.create(conn)

    # 1000000 rows
    for i in range(100):
        conn.execute(t1.insert(), [
            dict(
                ('d%d' % col, "data data data %d %d" % (col, (i * 10000) + j))
                for col in range(1, 6)
            ) for j in xrange(1, 10001)
        ])

import time

def timeit(fn, count, *args):
    now = time.time()
    for i in xrange(count):
        fn(*args)
    total = time.time() - now
    print "%s(%s): %f" % (fn.__name__, ",".join(repr(x) for x in args), total)

# this is a raw psycopg2 connection.
conn = engine.raw_connection()

def offset(limit, offset):
    cursor = conn.cursor()
    cursor.execute("select * from t1 order by id limit %d offset %d" % (limit, offset))
    cursor.fetchall()
    cursor.close()

def rownum(limit, offset):
    cursor = conn.cursor()
    cursor.execute("select * from (select *, "
                    "row_number() over (order by id asc) as rownum from t1) as foo "
                    "where rownum>=%d and rownum<%d" % (offset, limit + offset))
    cursor.fetchall()
    cursor.close()

def scroll(limit, offset):
    cursor = conn.cursor('foo')
    cursor.execute("select * from t1 order by id")
    cursor.scroll(offset)
    cursor.fetchmany(limit)
    cursor.close()

print 

timeit(offset, 10, 100, 100)
timeit(scroll, 10, 100, 100)
timeit(rownum, 10, 100, 100)

print 

timeit(offset, 10, 100, 480000)
timeit(scroll, 10, 100, 480000)
timeit(rownum, 10, 100, 480000)

print 

timeit(offset, 10, 100, 999900)
timeit(scroll, 10, 100, 999900)
timeit(rownum, 10, 100, 999900)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách ẩn trang trí tập hợp kết quả trong đầu ra Psql

  2. Người dùng Postgres không tồn tại?

  3. Thêm năm vào một ngày trong PostgreSQL

  4. Làm cách nào để thay đổi định dạng cho các giá trị trả về của tôi trong hàm này?

  5. Cách liệt kê Cơ sở dữ liệu và Bảng trong PostgreSQL bằng psql