Discusión sobre el artículo "Capacidades de SQLite en MQL5: Ejemplo de panel interactivo con estadísticas comerciales por símbolos y números mágicos" - página 2

 
SQLite: нативная работа с базами данных на SQL в MQL5
SQLite: нативная работа с базами данных на SQL в MQL5
  • 2020.02.18
  • www.mql5.com
Разработка торговых стратегий связана с обработкой больших объемов данных. Теперь прямо в MQL5 вы можете работать с базами данных с помощью SQL-запросов на основе SQLite. Важным преимуществом данного движка является то, что вся база данных содержится в единственном файле, который находится на компьютере пользователя.
 
Me precipité al juzgar sin profundizar en el fondo del asunto. Pido disculpas: me pasé con lo de «juguete para estudiantes»; SQLite no se merecía eso.

He profundizado más (con ayuda de la IA, Opus 5: monté un banco de pruebas, generé datos sintéticos para 500 000 operaciones, 20 símbolos y 20 indicadores, y realicé las mediciones). Esto es lo que se puede resumir.

1) Los cinco minutos de fxsaber casi seguro que NO se deben a SQLite.

INSERT de una sola operación con autocommit: ~245 segundos para 500 000.
Los mismos datos en un lote dentro de una sola transacción: 2,35 segundos.

Una diferencia de 104 veces. 245 segundos son exactamente esos mismos «cinco minutos». Cada inserción = una transacción independiente con fsync. Se soluciona con dos líneas: DatabaseTransactionBegin() / DatabaseTransactionCommit(). Todo lo demás en esta discusión, frente a esta cifra, son minucias.

2) Maxim tiene razón en lo que respecta a los índices, pero no a esos índices.

Consulta del artículo, esquema sin índices: 395 ms.
La misma consulta + un índice normal (MAGIC, ENTRY): 427 ms. Es decir, NO ayuda en absoluto.
La misma consulta + un índice de cobertura (MAGIC, ENTRY, PROFIT, SWAP, COMMISSION): 80 ms.

Para un GROUP BY completo, el índice normal no sirve de nada: la tabla se lee de todos modos en su totalidad, el plan SCAN ... USING INDEX es lo mismo que un escaneo. Es necesario que TODAS las columnas de la consulta estén en el índice; entonces, el plan pasa a ser SEARCH ... USING COVERING INDEX y ni siquiera se llega a las filas de la tabla. Ahí es cuando se multiplica por 5.

Y donde el índice realmente ayuda es en las selecciones por un solo símbolo, que el panel actualiza con cada redibujado: 20 consultas WHERE SYMBOL=? AND ENTRY=1: 711 ms sin índice frente a 208 ms con índice.

3) Sobre el array de estructuras. En esencia tengo razón, pero si se escribe una clase de envoltura propia con los índices y métodos necesarios. SQLite, por supuesto, reducirá el tiempo de desarrollo a costa del rendimiento y del consumo de recursos.

Lectura de 45,8 MB del archivo binario completo: 25 ms.
Una sola pasada, agregados por valores mágicos y por caracteres a la vez: 7 ms.
A modo de comparación: la descarga de las mismas 500 000 filas desde SQLite a una matriz de estructuras (ciclo DatabaseReadBind): 220 ms.

La mejora es real: entre 4 y 18 veces, dependiendo de la operación. Y la cifra de 220 ms frente a 25 ms es reveladora: si las estadísticas se calculan de todos modos en MQL5, la base de datos en este escenario funciona simplemente como un formato de archivo lento.

Pero la base de datos en disco ocupa 84 MB frente a los 46 MB del binario, y por esos 38 MB adicionales obtienes filtros arbitrarios, ordenaciones, paginación y cualquier informe nuevo sin coste alguno. En un array de estructuras no existen, a menos que las escribas a mano. Así que «no hace falta ninguna base de datos» es cierto exactamente hasta el momento en que se necesita una consulta que no hayas previsto de antemano. Enrique tiene razón en esto: si hay que CONSULTAR los datos, y no solo cargarlos, el SQL no tiene rival.

4) Me retracto de lo que dije sobre PostgreSQL.

Es un sistema cliente-servidor, no se puede integrar: proceso independiente, instalación, puertos, administración. Para un terminal de un solo usuario en un entorno de pruebas, esto no encaja desde el punto de vista arquitectónico. Y para el análisis local, SQLite suele ser incluso más rápido: no hay IPC ni idas y vueltas. El argumento sobre JSONB también se ha desmoronado: JSONB está presente en SQLite desde la versión 3.45, y para el historial de transacciones no se necesita JSON en absoluto, ya que allí las columnas están estrictamente tipificadas.

En resumen

La principal crítica al artículo se refiere al esquema y al código, no al motor. La diferencia entre «SQLite tal y como aparece en el artículo» y «SQLite bien implementado» es de cien veces. La diferencia entre un SQLite bien implementado y un array de estructuras es de unas pocas veces.

Y lo más acertado que se ha dicho en el hilo lo ha dicho 92746290: no volver a cargar todo el historial, sino completarlo a partir de la última transacción registrada. Esto soluciona el problema independientemente de si tienes un binario o una base de datos.

Si os interesa, puedo publicar el esquema con índices de cobertura, inserción por lotes y Sync() incremental, además de la versión con un array de estructuras.

Insisto: yo, por supuesto, utilizo clases ligeras con índices y los métodos necesarios, sin ninguna base de datos, lo que ofrece una clara ventaja en cuanto al consumo de recursos y al rendimiento.
 
Nikolai Semko #:
Me precipité al juzgar sin profundizar en el fondo del asunto. Pido disculpas: me pasé de la raya al hablar de «un juguete para estudiantes»; SQLite no se merecía eso.

Quizá no sea para estudiantes, pero sigue siendo un juguete. Al fin y al cabo, antes de usar SQLite hay que «revisar» todo el historial e introducir los datos en la tabla elemento por elemento. Y eso lleva muchísimo tiempo. Si ya hay que integrarlo en MQL5, entonces la lectura del historial de órdenes y operaciones también debería hacerse directamente en la tabla… En mi humilde opinión.

 
Nikolai Semko #:
He profundizado un poco más (con ayuda de la IA, Opus 5: he montado un entorno de pruebas, he generado datos sintéticos para 500 000 operaciones, 20 símbolos y 20 indicadores, y he ejecutado las mediciones).

A modo de reflexión: sería interesante compararlo con MonetDB/e. Es un sistema integrado sin servidor, igual que SQLite, pero por varias razones debería ser mucho más rápido con consultas complejas. Por supuesto, siempre que el esquema sea razonable :-)

 
Maxim Kuznetsov #:

A modo de reflexión: sería interesante compararlo con MonetDB/e. Es un sistema integrado sin servidor, igual que SQLite, pero, por diversas razones, debería ser mucho más rápido en consultas complejas. Por supuesto, siempre que el esquema sea razonable :-)

Quizás
Yo también había pensado en eso
Está mejor optimizado para matrices NoSQL
Hay que probarlo. Con la IA, ahora se puede comprobar rápidamente