У меня есть код Python, который ужасно медленный, поскольку ему приходится выполнять несколько циклов, и каждый цикл содержит свой собственный SQL-запрос.
Причина то есть каждый запрос извлекает переменную из столбца, который мне нужен для следующего цикла.
Основная идея заключается в том, что у меня есть лошадь H в гонке A
Теперь я хочу лошади H2, которые финишировали прямо перед лошадью H и позади нее, и получают их следующие две и последние скачки.
Оттуда я хочу, чтобы лошади, финишировавшие рядом с лошадьми H2, получили свои следующие две и последние скачки.
Вот пример того, как выглядит этот код: я добавил оператор создания таблицы и вставки, так что это рабочий код. Спасибо за ваши комментарии о том, как улучшить этот пример! >
import psycopg2
con = psycopg2.connect(
host='127.0.0.1',
port='5434',
user='postgres',
password='',
database=''
)
con.autocommit = False
cur = con.cursor()
create_table = '''
CREATE TABLE specific_winning_view2 (
racedate DATE,
racetime TIME WITHOUT TIME ZONE,
horsename VARCHAR,
track VARCHAR,
realpcb NUMERIC
);
'''
cur.execute(create_table)
con.commit()
create_table2 = '''
CREATE TABLE cross_table2 (
horsename VARCHAR,
realpcb NUMERIC
);
'''
cur.execute(create_table2)
con.commit()
insert_sql = '''
INSERT INTO specific_winning_view2 (racedate, racetime, horsename, track, realpcb)
VALUES
-- Gruppe 1: Werte für 10 Einträge
('2024-12-01', '14:00:00', 'Horse A1', 'Track A', 0.1),
('2024-12-01', '14:00:00', 'Horse A2', 'Track A', 0.2),
('2024-12-01', '14:00:00', 'Horse A3', 'Track A', 0.3),
('2024-12-01', '14:00:00', 'Horse A4', 'Track A', 0.4),
('2024-12-01', '14:00:00', 'Horse A5', 'Track A', 0.5),
('2024-12-01', '14:00:00', 'Horse A6', 'Track A', 0.6),
('2024-12-01', '14:00:00', 'Horse A7', 'Track A', 0.7),
('2024-12-01', '14:00:00', 'Horse A8', 'Track A', 0.8),
('2024-12-01', '14:00:00', 'Horse A9', 'Track A', 0.9),
('2024-12-01', '14:00:00', 'Horse A10', 'Track A', 1.0),
-- Gruppe 2: Werte für 10 Einträge
('2024-12-02', '15:30:00', 'Horse B1', 'Track B', 0.1),
('2024-12-02', '15:30:00', 'Horse B2', 'Track B', 0.2),
('2024-12-02', '15:30:00', 'Horse B3', 'Track B', 0.3),
('2024-12-02', '15:30:00', 'Horse B4', 'Track B', 0.4),
('2024-12-02', '15:30:00', 'Horse B5', 'Track B', 0.5),
('2024-12-02', '15:30:00', 'Horse B6', 'Track B', 0.6),
('2024-12-02', '15:30:00', 'Horse B7', 'Track B', 0.7),
('2024-12-02', '15:30:00', 'Horse B8', 'Track B', 0.8),
('2024-12-02', '15:30:00', 'Horse B9', 'Track B', 0.9),
('2024-12-02', '15:30:00', 'Horse B10', 'Track B', 1.0),
-- Gruppe 3: Werte für 10 Einträge
('2024-12-03', '16:15:00', 'Horse A1', 'Track C', 0.1),
('2024-12-03', '16:15:00', 'Horse B2', 'Track C', 0.2),
('2024-12-03', '16:15:00', 'Horse A3', 'Track C', 0.3),
('2024-12-03', '16:15:00', 'Horse B4', 'Track C', 0.4),
('2024-12-03', '16:15:00', 'Horse A5', 'Track C', 0.5),
('2024-12-03', '16:15:00', 'Horse B6', 'Track C', 0.6),
('2024-12-03', '16:15:00', 'Horse C7', 'Track C', 0.7),
('2024-12-03', '16:15:00', 'Horse C8', 'Track C', 0.8),
('2024-12-03', '16:15:00', 'Horse C9', 'Track C', 0.9),
('2024-12-03', '16:15:00', 'Horse C10', 'Track C', 1.0),
-- Gruppe 4: Werte für 10 Einträge
('2024-12-04', '17:45:00', 'Horse D1', 'Track D', 0.1),
('2024-12-04', '17:45:00', 'Horse D2', 'Track D', 0.2),
('2024-12-04', '17:45:00', 'Horse D3', 'Track D', 0.3),
('2024-12-04', '17:45:00', 'Horse D4', 'Track D', 0.4),
('2024-12-04', '17:45:00', 'Horse D5', 'Track D', 0.5),
('2024-12-04', '17:45:00', 'Horse A6', 'Track D', 0.6),
('2024-12-04', '17:45:00', 'Horse B7', 'Track D', 0.7),
('2024-12-04', '17:45:00', 'Horse A8', 'Track D', 0.8),
('2024-12-04', '17:45:00', 'Horse B9', 'Track D', 0.9),
('2024-12-04', '17:45:00', 'Horse A10', 'Track D', 1.0),
-- Gruppe 5: Werte für 10 Einträge
('2024-12-05', '18:30:00', 'Horse C1', 'Track E', 0.1),
('2024-12-05', '18:30:00', 'Horse C2', 'Track E', 0.2),
('2024-12-05', '18:30:00', 'Horse C3', 'Track E', 0.3),
('2024-12-05', '18:30:00', 'Horse C4', 'Track E', 0.4),
('2024-12-05', '18:30:00', 'Horse C5', 'Track E', 0.5),
('2024-12-05', '18:30:00', 'Horse C6', 'Track E', 0.6),
('2024-12-05', '18:30:00', 'Horse A7', 'Track E', 0.7),
('2024-12-05', '18:30:00', 'Horse A8', 'Track E', 0.8),
('2024-12-05', '18:30:00', 'Horse A9', 'Track E', 0.9),
('2024-12-05', '18:30:00', 'Horse A10', 'Track E', 1.0);
'''
cur.execute(insert_sql)
con.commit()
# First query: Fetch primary entries
first_sql ='''
SELECT racedate, racetime, track, realpcb, horsename
FROM specific_winning_view2
'''
cur.execute(first_sql)
first_sql_r = cur.fetchall()
aaa = 0
for _ in first_sql_r:
primary_date = first_sql_r[aaa][0]
primary_time = first_sql_r[aaa][1]
primary_track = first_sql_r[aaa][2]
primary_realpcb = first_sql_r[aaa][3]
primary_horse = first_sql_r[aaa][4]
aaa += 1
first_race_detail_sql = '''
SELECT horsename, racedate
FROM (
SELECT *
FROM specific_winning_view2
WHERE racedate = %s
AND racetime = %s
AND track = %s
AND realpcb < %s
ORDER BY realpcb DESC
LIMIT 2
) lower_entries
UNION ALL
SELECT horsename, racedate
FROM (
SELECT *
FROM specific_winning_view2
WHERE racedate = %s
AND racetime = %s
AND track = %s
AND realpcb > %s
ORDER BY realpcb ASC
LIMIT 2
) higher_entries
'''
cur.execute(first_race_detail_sql, (primary_date, primary_time, primary_track, primary_realpcb, primary_date, primary_time, primary_track, primary_realpcb))
first_race_detail_sql_r = cur.fetchall()
bbb = 0
for _ in first_race_detail_sql_r:
first_race_horsename = first_race_detail_sql_r[bbb][0]
bbb += 1
if first_race_horsename != primary_horse:
##
# Rennen der Pferde, die um das Original Pferd platziert haben, als Liste - jeweils 2 davor und 2 danach
##
second_race_sql = '''
(
SELECT racedate, racetime, track, realpcb
FROM specific_winning_view2
WHERE racedate < %s
AND horsename = %s
ORDER BY racedate DESC
LIMIT 1
)
UNION ALL
(
SELECT racedate, racetime, track, realpcb
FROM specific_winning_view2
WHERE racedate > %s
AND horsename = %s
ORDER BY racedate ASC
LIMIT 2
)
ORDER BY racedate;
'''
cur.execute(second_race_sql, (primary_date, first_race_horsename, primary_date, first_race_horsename))
second_race_sql_r = cur.fetchall()
ccc = 0
for _ in second_race_sql_r:
## Next loop, same as above
second_racedate = second_race_sql_r[ccc][0]
second_racetime = second_race_sql_r[ccc][1]
second_track = second_race_sql_r[ccc][2]
second_realpcb = second_race_sql_r[ccc][3]
ccc += 1
second_race_detail_sql = '''
SELECT horsename, realpcb, racedate
FROM (
SELECT *
FROM specific_winning_view2
WHERE racedate = %s
AND racetime = %s
AND track = %s
AND realpcb < %s
ORDER BY realpcb DESC
LIMIT 2
) lower_entries
UNION ALL
SELECT horsename, realpcb, racedate
FROM (
SELECT *
FROM specific_winning_view2
WHERE racedate = %s
AND racetime = %s
AND track = %s
AND realpcb > %s
ORDER BY realpcb ASC
LIMIT 2
) higher_entries
'''
cur.execute(second_race_detail_sql, (second_racedate, second_racetime, second_track, second_realpcb, second_racedate, second_racetime, second_track, second_realpcb))
second_race_detail_sql_r = cur.fetchall()
ddd = 0
for _ in second_race_detail_sql_r:
second_race_horsename = second_race_detail_sql_r[ddd][0]
second_real_pcb = second_race_detail_sql_r[ddd][1]
second_race_racedate = second_race_detail_sql_r[ddd][2]
if second_race_horsename != first_race_horsename:
third_race_sql = '''
(
SELECT racedate, racetime, track, realpcb
FROM specific_winning_view2
WHERE racedate < %s
AND horsename = %s
ORDER BY racedate DESC
LIMIT 1
)
UNION ALL
(
SELECT racedate, racetime, track, realpcb
FROM specific_winning_view2
WHERE racedate > %s
AND horsename = %s
ORDER BY racedate ASC
LIMIT 2
)
ORDER BY racedate;
'''
cur.execute(third_race_sql, (second_race_racedate, second_race_horsename, second_race_racedate, second_race_horsename))
third_race_sql_r = cur.fetchall()
eee = 0
for _ in third_race_sql_r:
third_racedate = third_race_sql_r[eee][0]
third_racetime = third_race_sql_r[eee][1]
third_track = third_race_sql_r[eee][2]
third_realpcb = third_race_sql_r[eee][3]
eee += 1
##
# Rennen der Pferde, die gegen das Zweite-Pferd im zweiten Rennen gelaufen sind
# Inklusive der Pferde, die zwei Plätze davor und dahinter platziert haben (Cross-Cross)
##
third_race_detail_sql = '''
SELECT horsename, realpcb
FROM (
SELECT *
FROM specific_winning_view2
WHERE racedate = %s
AND racetime = %s
AND track = %s
AND realpcb < %s
ORDER BY realpcb DESC
LIMIT 2
) lower_entries
UNION ALL
SELECT horsename, realpcb
FROM (
SELECT *
FROM specific_winning_view2
WHERE racedate = %s
AND racetime = %s
AND track = %s
AND realpcb > %s
ORDER BY realpcb ASC
LIMIT 2
) higher_entries
'''
cur.execute(third_race_detail_sql, (third_racedate, third_racetime, third_track, third_realpcb, third_racedate, third_racetime, third_track, third_realpcb))
third_race_detail_sql_r = cur.fetchall()
fff = 0
for _ in third_race_detail_sql_r:
third_race_horsename = third_race_detail_sql_r[fff][0]
third_real_pcb = third_race_detail_sql_r[fff][1]
try:
insert_into_sql2 = '''
INSERT INTO cross_table2 (horsename, realpcb)
VALUES (%s, %s)
'''
cur.execute(insert_into_sql2, (third_race_horsename, third_real_pcb))
con.commit()
except Exception as e:
print('SQL Exception 1, ', e)
cur.close()
con.close()
Это, конечно, очень медленно из-за большого количества запросов к базе данных, но я просто недостаточно хорошо разбираюсь в SQL, чтобы придумать способ уменьшить количество запросов, которые я делаю. нужно сделать, чтобы получить то, что я хочу.
Результаты затем вводятся один за другим в другую таблицу.
Я читаю о том, как ускорить SQL-запросы, но ничто из того, что я читаю, не помогает мне уменьшить количество циклов/запросов в циклы, но я уверен, что есть лучший способ сделать это.
Можно ли ускорить это? Меньше запросов или более эффективные запросы к базе данных?
У меня есть код [b]Python[/b], который ужасно медленный, поскольку ему приходится выполнять несколько циклов, и каждый цикл содержит свой собственный SQL-запрос. Причина то есть каждый запрос извлекает переменную из столбца, который мне нужен для следующего цикла. Основная идея заключается в том, что у меня есть лошадь H в гонке A Теперь я хочу лошади H2, которые финишировали прямо перед лошадью H и позади нее, и получают их следующие две и последние скачки. Оттуда я хочу, чтобы лошади, финишировавшие рядом с лошадьми H2, получили свои следующие две и последние скачки. Вот пример того, как выглядит этот код: я добавил оператор создания таблицы и вставки, так что это рабочий код. [b]Спасибо за ваши комментарии о том, как улучшить этот пример![/b] > [code]import psycopg2
con = psycopg2.connect( host='127.0.0.1', port='5434', user='postgres', password='', database='' ) con.autocommit = False cur = con.cursor()
create_table = ''' CREATE TABLE specific_winning_view2 ( racedate DATE, racetime TIME WITHOUT TIME ZONE, horsename VARCHAR, track VARCHAR, realpcb NUMERIC ); ''' cur.execute(create_table) con.commit()
first_race_detail_sql = ''' SELECT horsename, racedate FROM ( SELECT * FROM specific_winning_view2 WHERE racedate = %s AND racetime = %s AND track = %s AND realpcb < %s ORDER BY realpcb DESC LIMIT 2 ) lower_entries UNION ALL SELECT horsename, racedate FROM ( SELECT * FROM specific_winning_view2 WHERE racedate = %s AND racetime = %s AND track = %s AND realpcb > %s ORDER BY realpcb ASC LIMIT 2 ) higher_entries ''' cur.execute(first_race_detail_sql, (primary_date, primary_time, primary_track, primary_realpcb, primary_date, primary_time, primary_track, primary_realpcb)) first_race_detail_sql_r = cur.fetchall()
bbb = 0 for _ in first_race_detail_sql_r: first_race_horsename = first_race_detail_sql_r[bbb][0]
bbb += 1 if first_race_horsename != primary_horse: ## # Rennen der Pferde, die um das Original Pferd platziert haben, als Liste - jeweils 2 davor und 2 danach ## second_race_sql = ''' ( SELECT racedate, racetime, track, realpcb FROM specific_winning_view2 WHERE racedate < %s AND horsename = %s ORDER BY racedate DESC LIMIT 1 ) UNION ALL ( SELECT racedate, racetime, track, realpcb FROM specific_winning_view2 WHERE racedate > %s AND horsename = %s ORDER BY racedate ASC LIMIT 2 ) ORDER BY racedate; ''' cur.execute(second_race_sql, (primary_date, first_race_horsename, primary_date, first_race_horsename)) second_race_sql_r = cur.fetchall()
ccc = 0 for _ in second_race_sql_r: ## Next loop, same as above second_racedate = second_race_sql_r[ccc][0] second_racetime = second_race_sql_r[ccc][1] second_track = second_race_sql_r[ccc][2] second_realpcb = second_race_sql_r[ccc][3] ccc += 1
second_race_detail_sql = ''' SELECT horsename, realpcb, racedate FROM ( SELECT * FROM specific_winning_view2 WHERE racedate = %s AND racetime = %s AND track = %s AND realpcb < %s ORDER BY realpcb DESC LIMIT 2 ) lower_entries UNION ALL SELECT horsename, realpcb, racedate FROM ( SELECT * FROM specific_winning_view2 WHERE racedate = %s AND racetime = %s AND track = %s AND realpcb > %s ORDER BY realpcb ASC LIMIT 2 ) higher_entries ''' cur.execute(second_race_detail_sql, (second_racedate, second_racetime, second_track, second_realpcb, second_racedate, second_racetime, second_track, second_realpcb)) second_race_detail_sql_r = cur.fetchall()
ddd = 0 for _ in second_race_detail_sql_r: second_race_horsename = second_race_detail_sql_r[ddd][0] second_real_pcb = second_race_detail_sql_r[ddd][1] second_race_racedate = second_race_detail_sql_r[ddd][2] if second_race_horsename != first_race_horsename: third_race_sql = ''' ( SELECT racedate, racetime, track, realpcb FROM specific_winning_view2 WHERE racedate < %s AND horsename = %s ORDER BY racedate DESC LIMIT 1 ) UNION ALL ( SELECT racedate, racetime, track, realpcb FROM specific_winning_view2 WHERE racedate > %s AND horsename = %s ORDER BY racedate ASC LIMIT 2 ) ORDER BY racedate; ''' cur.execute(third_race_sql, (second_race_racedate, second_race_horsename, second_race_racedate, second_race_horsename)) third_race_sql_r = cur.fetchall()
eee = 0 for _ in third_race_sql_r:
third_racedate = third_race_sql_r[eee][0] third_racetime = third_race_sql_r[eee][1] third_track = third_race_sql_r[eee][2] third_realpcb = third_race_sql_r[eee][3] eee += 1 ## # Rennen der Pferde, die gegen das Zweite-Pferd im zweiten Rennen gelaufen sind # Inklusive der Pferde, die zwei Plätze davor und dahinter platziert haben (Cross-Cross) ##
third_race_detail_sql = ''' SELECT horsename, realpcb FROM ( SELECT * FROM specific_winning_view2 WHERE racedate = %s AND racetime = %s AND track = %s AND realpcb < %s ORDER BY realpcb DESC LIMIT 2 ) lower_entries UNION ALL SELECT horsename, realpcb FROM ( SELECT * FROM specific_winning_view2 WHERE racedate = %s AND racetime = %s AND track = %s AND realpcb > %s ORDER BY realpcb ASC LIMIT 2 ) higher_entries ''' cur.execute(third_race_detail_sql, (third_racedate, third_racetime, third_track, third_realpcb, third_racedate, third_racetime, third_track, third_realpcb)) third_race_detail_sql_r = cur.fetchall()
try: insert_into_sql2 = ''' INSERT INTO cross_table2 (horsename, realpcb) VALUES (%s, %s) ''' cur.execute(insert_into_sql2, (third_race_horsename, third_real_pcb)) con.commit() except Exception as e: print('SQL Exception 1, ', e) cur.close() con.close() [/code] Это, конечно, очень медленно из-за большого количества запросов к базе данных, но я просто недостаточно хорошо разбираюсь в SQL, чтобы придумать способ уменьшить количество запросов, которые я делаю. нужно сделать, чтобы получить то, что я хочу. Результаты затем вводятся один за другим в другую таблицу. Я читаю о том, как ускорить SQL-запросы, но ничто из того, что я читаю, не помогает мне уменьшить количество циклов/запросов в циклы, но я уверен, что есть лучший способ сделать это. Можно ли ускорить это? Меньше запросов или более эффективные запросы к базе данных?