Comparer Querydsl, jOOQ, JEQUEL, activejdbc, iciql et D'autres requêtes DSLs
Quelqu'un peut-il m'indiquer quelques ressources sur la comparaison des performances entre les différentes bibliothèques de requêtes DSL disponibles pour utilisation avec Java, comme: Querydsl, jOOQ, JEQUEL,activejdbc, iciql et etc...
Contexte: j'utilise le modèle JDBC du printemps, mais cela nécessitait quand même que les requêtes soient écrit en format chaîne simple. Bien que je n'ai pas de problèmes pour écrire les requêtes directes, mais je m'inquiète d'avoir une dépendance directe sur les noms de tables DB. Je ne veux pas utiliser de cadre ORM comme Hibernate ou JPA/EclipseLink. J'ai besoin de performances brutes aussi élevées que possible (IMO, ils sont bons pour les applications plus CRUD centric). Je peux me permettre un peu de surplace pour ces DSL seulement si c'est un peu (je crois, ce sera surtout des concaténations StringBuilder/String!)
j'ai envisagé d'utiliser des requêtes nommées externalisées dans certains xml. Mais j'essaie juste d'évaluer la valeur des différentes bibliothèques de requêtes DSL.
Edit: de plus sur mon exigence: Je veux connaître la comparaison des performances entre ceux-ci lors de la construction d'une requête modérément complexe en utilisant leurs méthodes API. Tout ce dont j'ai besoin est de générer une chaîne de requête en utilisant n'importe laquelle de ces bibliothèques DSL de requête et passer cela au modèle JDBC de printemps. Donc, je veux savoir si l'ajout de cette intermediate step encourt une pénalité de performance considérable, je veux utiliser des requêtes nommées ou construire ma propre bibliothèque qui utilise StingBuilder ou une approche similaire
mise à jour mon expérience avec jOOQ, iciql, QueryDSL:
bien que j'ai oublié de mentionner ceci dans mon post d'origine, je suis également passionné par la facilité d'utilisation et les frais généraux que j'ai besoin d'avoir dans mes classes d'entités (comme si des annotations ou des implémentations supplémentaires nécessaires).
jOOQ:
- nécessite de changer les propriétés de l'entité à la bibliothèque de façon spécifique
- peut retourner chaîne de requête SQL
Iciql:
- entité peut être mappé avec pas ou peu de changements (peut être cartographiés à l'aide d'total de 3 façons)
- mais avec cela il limite à sélectionner seulement les requêtes (pour update/delete/... nécessite entité changements de nouveau)
QueryDSL:
- plusieurs façons de lier les entities avec table (autres que les façons spécifiques aux bibliothèques, l'utilisation des annotations JPA est supportée). mais nous devons modifier les entités au moins
- pas de moyen simple/direct pour obtenir la chaîne de requête
(toutes les observations sont avec peu de connaissances que j'ai sur ces; si l'une de celles-ci sont incorrectes, veuillez corriger)
avec tout ce qui précède, je m'en tiens à l'écriture nommée questions: (mais comme la réponse de Lukas Eder semble expliquer sur mon premier post concern (performance), j'ai accepté le sien.
3 réponses
dans les JVM modernes, vous ne devriez pas trop vous soucier de la concaténation des chaînes SQL. Le vrai overhead qu'une couche d'abstraction de base de données peut produire (par rapport au temps relativement élevé d'aller-retour vers la base de données et retour), est généralement dû à la mise en cache de deuxième niveau, qui est fait dans Hibernate/JPA. Ou encore, en établissant une correspondance inefficace entre les modèles d'objets et SQL, de sorte qu'il devient impossible d'utiliser des index ou de transformer des requêtes générales.
Comparé à cela, la concaténation de chaîne est vraiment négligeable, même pour les constructions complexes de SQL avec plusieurs UNIONs
, imbriquée SELECTs
,JOINs
, semi-JOINs
,anti-JOINs
, etc, Donc je devine que tous les cadres que vous avez mentionnés fonctionnent de manière similaire, car ils vous permettent de garder le contrôle sur votre SQL.
d'un autre côté, certains cadres ou modes d'utilisation dans ces cadres peuvent effectivement récupérer l'ensemble du résultat en mémoire. Cela peut causer des problèmes si vos ensembles de résultats sont grands, aussi parce que, avec les génériques de Java, la plus primitive types (int
,long
, etc) sont probablement mappés sur leurs enveloppes correspondantes (Integer
,Long
).
jOOQ (dont je suis le développeur), j'ai déjà profilé la bibliothèque avec YourKit Profiler massive pour l'exécution de la requête. Le gros du travail a toujours été fait dans la base de données, et non dans la construction des requêtes. jOOQ utilise un simple StringBuilder
pour chaque requête. J'imagine (non vérifié), que QueryDSL et JEQUEL faire la même chose...
iciql, qui est une fourchette de JaQu, il pourrait y avoir un impact supplémentaire par le fait qu'ils utilisent l'instrumentation Java pour décompiler leur naturel de syntaxe. Mais je suppose que cela peut être omis, si cela signifie Trop d'impact.
Vous devriez aussi regarder MyBatis Statement Builder.
alors que MyBatis est clairement une technologie de cartographie, il a un constructeur de déclaration DSL qui semble être découplé de MyBatis (c'est-à-dire que vous n'avez besoin de rien d'autre de MyBatis pour utiliser les constructeurs... fâcheusement elle n'est pas dans son propre pot). Je n'aime pas ça parce qu'il utilise des ThreadLocals.
Je ne peux pas parler pour d'autres cadres, mais j'ai effectué une analyse primitive de la performance pour comparer ActiveJDBC et Hibernate. Le test était sur un ordinateur portable avec 8G RAM, disque SSD contre MySQL. Les gens de Table avec quelques colonnes simples et une ID PK de substitution.
un test était d'insérer des enregistrements 50K comme objets, et l'autre était de lire les objets 50K de la table à la fois (en mémoire). Dans les deux tests, L'ActiveJDBC a montré une amélioration de 40% de la performance par rapport à L'hibernation. Dans dans les deux cas, les requêtes générées étaient insert simple et select, ressemblant étroitement l'un à l'autre.
j'espère que cette aide,
Igor