2016-11-15 5 views
0

У меня есть база данных Postgre, которую я обновляю каждый день, чтобы хранить биржевые тикеры и цены. Я использую эту базу данных для загрузки цен на акции для разных дат в сценарии, над которым я работаю. Тем не менее, я заметил, что запросы операторов SQL занимают значительно больше времени для выполнения при выполнении в Python по сравнению с командной строкой psql.Улучшение производительности нескольких SQL-запросов в python

Кто-нибудь знает, что я могу сделать, чтобы улучшить производительность кода ниже? Я попытался объединить SQL-запросы в один длинный запрос, но он, похоже, не работает. Спасибо!

for ticker in sectorStocks: 

    # Pull closing price for startDate 
    with con: 
     cur = con.cursor() 
     cur.execute("SELECT close_price FROM dailyprices WHERE ticker=%s AND price_date=%s", (ticker,startDate)) 
     tickerStartRaw = cur.fetchone() 

    # Check to ensure there is market data for the date used 
    while not tickerStartRaw: 
     startDate = startDate - BDay(1) 
     with con: 
      cur = con.cursor() 
      cur.execute("SELECT close_price FROM dailyprices WHERE ticker=%s AND price_date=%s", (ticker,startDate)) 
      tickerStartRaw = cur.fetchone() 

    tickerStartPrice = tickerStartRaw[0] 

    # Pull closing price for endDate 
    with con: 
     cur = con.cursor() 
     cur.execute("SELECT close_price FROM dailyprices WHERE ticker=%s AND price_date=%s", (ticker,endDate)) 
     tickerEndRaw = cur.fetchone() 

    # Check to ensure there is market data for the date used 
    while not tickerEndRaw: 
     endDate = endDate - BDay(1) 
     with con: 
      cur = con.cursor() 
      cur.execute("SELECT close_price FROM dailyprices WHERE ticker=%s AND price_date=%s", (ticker,endDate)) 
      tickerEndRaw = cur.fetchone() 

    tickerEndPrice = tickerEndRaw[0] 
+1

Код выглядит прочным. Пробовали ли вы использовать модуль 'timeit' для диагностики того, какая часть кода вызывает задержку? EDIT: Я просто заметил цикл 'for' в верхней части кода. Насколько велик «сектор»? Может быть, накладные расходы на открытие и закрытие всех этих соединений замедляют вас. – James

+1

Убедитесь, что есть указатель на столбцы 'ticker' и' price_date'. – MrEricSir

+1

В принципе, вам нужно избавиться от трех циклов в вашем коде. Для получения более подробной справки вам необходимо предоставить структуру таблицы, некоторые примерные данные и желаемый результат. –

ответ

0

Не знаком с python, но используйте переменные bind (не верьте, поэтому этот синтаксис python).

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

В этом случае каждый оператор SQL будет рассматриваться как новый и требует разбора каждый раз. Для большого объема запросов это может иметь большое значение.

+0

Я рассмотрю привязку startDate и endDate. Учитывая, что я разбираю 400 + тикеры, это может помочь – JDGD

+0

определенно и будет масштабироваться лучше, поскольку вы добавляете больше тикеров –

0

После того, как я понял, что единственной реальной проблемой была задержка с тысячами запросов к базе данных.

Я смог значительно улучшить время сценария, расчесывая все SQL-тяги в один оператор. Я также занимаюсь созданием одного исходного дампа данных из базы данных для всех используемых «тикеров», так что весь скрипт использует только один SQL-pull.

for ticker in sectorStocks: 
     with con: 
      cur = con.cursor() 
      cur.execute("SELECT price_date, close_price FROM dailyprices WHERE ticker=%s AND (price_date=%s or price_date=%s)", (ticker, startDate, endDate)) 
      tickerPricesRaw = cur.fetchall() 

     if(len(tickerPricesRaw) < 2): 
      print("Error pulling price data for %s - going to next ticker" % ticker) 
      continue 
     else: 
      ...... 
Смежные вопросы