2011-07-06 18 views
19

Soy un usuario R, y con frecuencia me parece que necesito escribir funciones que requieren subconjunto de grandes conjuntos de datos (10 de millones de filas). Cuando aplico tales funciones en un gran número de observaciones, puede tomar mucho tiempo si no tengo cuidado con la forma en que lo implemento.La manera más rápida de subconjunto - data.table contra MySQL

Para hacer esto, algunas veces he usado el paquete data.table, y esto proporciona velocidades mucho más rápidas que el subconjunto usando marcos de datos. Recientemente, comencé a experimentar con paquetes como RMySQL, empujé algunas tablas a mysql y usé el paquete para ejecutar consultas SQL y devolver resultados.

He encontrado mejoras en el rendimiento mixto. Para conjuntos de datos más pequeños (millones), parece que cargar los datos en una tabla de datos y configurar las claves correctas hace que los subconjuntos sean más rápidos. Para conjuntos de datos más grandes (10 a 100 s de millones), parece que el envío de una consulta a mysql se mueve más rápido.

¿Se preguntaba si alguien tiene alguna idea de qué técnica debería devolver consultas de agregación o agregación simples más rápido, y si esto debería depender del tamaño de los datos? Entiendo que establecer claves en data.table es algo similar a crear un índice, pero no tengo mucha más intuición más allá de eso.

+0

Sé que algunas otras personas aquí tienen más experiencia con esto, así que les dejaré exponerlo con las respuestas reales, pero sospecho que querrás mirar el paquete 'sqldf' que hace exactamente lo que eres describiendo, solo crea la tabla en la memoria (creo) para que las consultas puedan correr un poco más rápido. – joran

+0

gracias, joran! Tengo ganas de entender esto en el contexto de tablas grandes. Todo es especulación, pero he recibido consejos de que los problemas de velocidad que tengo podrían deberse a limitaciones/administración de la memoria. Después de todo, cuando se usan datos.mesa, ¿no son esas tablas en la memoria también? – exl

+0

De hecho, para los datos que la memoria grande será un problema, pero creo que sqldf también puede usar discos db. De nuevo, no lo he usado mucho, lo mencioné porque es un paquete completo basado en el concepto de enviar datos a una base de datos, realizar SQL y luego devolverlo a R. – joran

Respuesta

25

Si los datos encajan en la RAM, data.table es más rápido. Si proporciona un ejemplo, probablemente se volverá evidente, rápidamente, que está usando data.table mal. ¿Has leído los "qué hacer y qué no hacer" en el data.table wiki?

SQL tiene un límite inferior porque es una tienda de filas. Si los datos encajan en la RAM (y 64 bits son bastante), data.table es más rápido no solo porque está en la RAM, sino porque las columnas son contiguas en la memoria (minimizando la obtención de páginas de la RAM a L2 para las operaciones de columna). Use data.table correctamente y debe ser más rápido que el límite inferior de SQL. Esto se explica en la Pregunta frecuente 3.1. Si estás viendo más lento con data.table, entonces es muy probable que estés usando data.table incorrectamente (o hay un error de rendimiento que tenemos que corregir). Por lo tanto, publique algunas pruebas, después de leer la wiki de data.table.

+1

Doyle - ¡Agradable! Yo también me dirijo a la wiki yo mismo. Siempre he entendido que el Db es más rápido para la mayoría de las consultas, pero ahora puedo verificar por qué y cuáles son esos límites. A veces uno necesita un punto en la dirección correcta. . . ¡Gracias! – XIVSolutions

2

No soy un usuario R, pero sé un poco acerca de las Bases de datos. Creo que MySQL (o cualquier otro RDBMS reputable) realmente realizará sus operaciones de subconjuntos más rápidamente (por ejemplo, un orden de magnitud, generalmente), salvo cualquier cálculo adicional involucrado en el proceso de subconjunto.

Sospecho que su retraso de rendimiento en pequeños conjuntos de datos está relacionado con el gasto de la conexión y el empuje inicial de los datos a MySQL. Es probable que haya un punto en el que la sobrecarga de la conexión y el tiempo de transferencia de datos agreguen más al costo de su operación que lo que MySQL le está ahorrando.

Sin embargo, para conjuntos de datos mayores que un cierto mínimo, parece probable que este costo se compense por la gran velocidad de la base de datos.

Mi comprensión es que SQL puede lograr la mayoría de las operaciones de búsqueda y clasificación mucho, mucho más rápidamente que las operaciones iterativas en el código. Pero uno debe tener en cuenta el costo de la conexión y (en este caso) la transferencia inicial de datos a través del cable de red.

Estaré interesado en escuchar lo que otros tienen que decir. . .

+0

gracias por la publicación! solo una aclaración: no envío conjuntos de datos a MySQL en cada iteración; más bien, lo hago una vez antes de ejecutar la función. Por lo tanto, solo tengo que expulsar de R a MySQL para que la iteración de alcance sea un valor o un vector para que la consulta se subconjuebe. – exl

+0

Hmm. Todavía estaré interesado en la razón detrás del cambio en las estadísticas de rendimiento entre los conjuntos de datos "pequeños" y "grandes". ¿Posiblemente todavía está relacionado con la sobrecarga de conexión, incluso sin el empuje? (por ejemplo, gastos generales de conexión como porcentaje del tiempo total de ejecución) – XIVSolutions

Cuestiones relacionadas