2016-02-01 1 views
2

Я пытаюсь перенести R-код на Python 2.7, чтобы сравнить оба. Первая проблема, которую я получаю, - это когда я пытаюсь выполнить соединение odbc. R намного быстрее, чем python, но поскольку я новичок в Python, я не уверен, использую ли я правильный пакет.Python 2.7 pyodbc или pymssql vs R RODBC

В РИ пишут:

ptm <- proc.time() 
require(RODBC) 
dbXX <- odbcDriverConnect('driver={SQL Server}; 
    server=s001111;database=XX;trusted_connection=true') 
rech<-sqlQuery(dbXX, "select top 10000* from XX.dbo.table ", as.is=T) 
proc.time() - ptm 

и я получаю:

> proc.time() - ptm 
    user system elapsed 
    2.47 0.11 2.87 

Я скачал Anaconda для питона 2.7 окна 7 64. Так Spyder я пишу:

import pyodbc 
import pandas 
from pandas.io.sql import read_frame 
sql = 'select top 10000 * from XX.dbo.table' 
cnn = pyodbc.connect('DRIVER={SQL Server};SERVER=s001111;DATABASE=XX;Trusted_Connection=yes') 

start = time.time() 
data=pd.read_sql(sql,cnn) 
end = time.time() 
print(end - start) 

Это займет 6,35 сек.

Я также попытался с pymssql:

import pymssql 
conn = pymssql.connect(server='s001111', database='XX') 
start = time.time() 
data=pd.read_sql(sql,conn) 
end = time.time() 
print(end - start) 

Это занимает 38,3 секунд!

Реальный запрос должен прочитать таблицу, размер которой составляет 220 000 строк по 353 столбцам и применить фильтр (с помощью которого).

Мне нужно только выдержка данные от db.

Есть ли способ сделать это быстрее в Python 2.7?

Я нашел pyodbc-memory usage relation caused by SQL Server, но я предполагаю, что если бы это была проблема SQL, она бы делала то же самое в R, не так ли?

Я также нашел это: IOPro, но это не бесплатно!

В этот момент мне было интересно, если проблема была связь ODBC или сам панды, поэтому я попытался:

cur = conn.cursor(); 
start = time.time() 
cur.execute(sql); 
tabla=cur.fetchall() 
end = time.time() 
print(end - start) 

Но потребовалось 29,29 сек.

Итак, как же: возможно ли, что R намного быстрее, чем Python для извлечения данных из базы данных SQL Microsoft?

+1

Производительность может быть очень зависит от используемого драйвера. Я бы предложил попробовать другой драйвер, чтобы убедиться, что это работает лучше. Например, альтернатива - '' pymssql'' (https://pypi.python.org/pypi/pymssql/2.1.1). См. Также список здесь: http://docs.sqlalchemy.org/en/rel_1_0/dialects/mssql.html – joris

+1

Кроме того, небольшое примечание: 'read_frame' устарело, вы должны использовать' pd.read_sql' вместо этого. Я также рекомендую использовать 'SQLAlchemy' для указания соединения (но это не зависит от используемого драйвера). См. Http://pandas.pydata.org/pandas-docs/stable/io.html#sql-queries – joris

+0

@joris благодарит! Я загрузил с conda pymssql. Также написал код и запустил его. Как измерить время, требуемое для каждой библиотеки? Я думаю, что все еще требуется гораздо больше времени, чем R-код ... это возможно? – GabyLP

ответ

3

Как RODBC, так и pyodbc, вероятно, потратят большую часть времени на передачу данных с сервера базы данных на локальный компьютер, который вы используете для запуска вашего запроса. Очень важным параметром здесь является количество строк, перемещенных с сервера db на локальный компьютер для каждого цикла выборки. И RODBC, и pyodbc позволяют вам настроить этот параметр.

Теперь, если вы хотите, чтобы сравнивать яблоки с яблоками:

  1. использует ту же инфраструктуру: такой же удаленный дб, тот же локальный клиент, такие же сети между
  2. использует один и тот же ODBC слой: тот же менеджер водителя , тот же самый драйвер, тот же самый DSN
  3. извлекает точно столько же строк для каждого цикла выборки как с R, так и с питоном. Имейте в виду: если вы ничего не скажете, то sqlQuery() из RODBC будет извлекать по 100 строк за раз!

Я использовал этот подход для сравнения RODBC и pyobbc с тремя различными базами данных (не включая SQL Server), и я всегда считаю, что характеристики сопоставимы.

Вот код R:

library(RODBC) 
ch <- odbcConnect("DWN",uid="xyz",pwd="xyz",rows_at_time=1024); 
ds <- sqlQuery(ch,"select * from large_table limit 100000"); 

И вот у вас есть код Python:

>>> import pyodbc 
>>> ch = pyodbc.connect('DSN=xyz;UID=xyz;PWD=xyz') 
>>> curs = ch.cursor() 
>>> curs.execute("select * from large_table limit 100000") 
>>> while True: 
...  rows = curs.fetchmany(1024) 
...  if not rows: 
...   break 
... 
>>> 
Смежные вопросы