[spip-dev] Question à deux sous : serait-ce possible de cacher nativement les requêtes SQL ?

Salut la liste,

pourrait-on avoir un paramètre supplémentaire dans les fonctions de l’API SQL pour gérer un cache du résultat d’une requête (par cache SQL, APC, memcached, xcache ou autre) ?
J’ai certaines requêtes trop lourdes et répétitives que je peux optimiser de manière séparées, mais il me semble que l’idéal serait que ce soit nativement pris en compte dans les fonctions abstraites.
J’y verrais aussi un avantage à ajouter un critère de cache dans les boucles SPIP.

Qu’en pensez-vous ?

.Gilles

pourrait-on avoir un paramètre supplémentaire dans les fonctions de l'API
SQL pour gérer un cache du résultat d'une requête (par cache SQL, APC,
memcached, xcache ou autre) ?

C'est une bonne idée de permettre ça, mais cette API a déjà trop de
paramètres, c'est l'enfer à utiliser... Je préférerais qu'on la
réécrive avec un simple array() en premier paramètre, de cette manière
:

sql_xxx(array( 'from' => xxx, 'where' => yyy, cache=>true))

J'ai certaines requêtes trop lourdes et répétitives que je peux optimiser de
manière séparées, mais il me semble que l'idéal serait que ce soit
nativement pris en compte dans les fonctions abstraites.

Oui ; attention toutefois à ne pas doublonner avec le query cache de MySQL.

J'y verrais aussi un avantage à ajouter un critère de cache dans les boucles
SPIP.

Quoi qu'il en soit je t'invite à tester ce genre de développements
dans le plugin memoization.

-- Fil

pourrait-on avoir un paramètre supplémentaire dans les fonctions de l'API
SQL pour gérer un cache du résultat d'une requête (par cache SQL, APC,
memcached, xcache ou autre) ?

C'est une bonne idée de permettre ça, mais cette API a déjà trop de
paramètres, c'est l'enfer à utiliser... Je préférerais qu'on la
réécrive avec un simple array() en premier paramètre, de cette manière

Au fait, je ne sais pas sous quelle forme on mémoizerait le résultat
d'un select : faut-il stocker toutes les rows renvoyées ? Si oui
ensuite il devient difficile de les dérouler dans des sql_fetch()
successifs sans retomber sur ... la boucle POUR.

-- Fil

Argh…
esj : est-ce que tu as une idée de ce que ça impacterait sur le noyau ?

2010/8/26 Fil <fil@rezo.net>

Il y a déjà un cache dans le serveur SQL, je suis sceptique sur l'intérêt de gérer un cache avec ce bourrin de PHP.

Committo,Ergo:Sum

Ah, ça dépend des systèmes de cache.
Certains peuvent stocker des objets (APC par ex.), d’autres que des variables statiques (xcache, eaccelerator, et fichier)
– Ah, mince, la dernière version d’eaccelerator ne fait plus de cache :confused: –
ça peut quand même se sérializer / desérialiser comme le code ci-dessous :
http://www.zeger.nl/node/13

Un test sur le type du résultat d’une requete, ou une variable globale, permettrait de différer les traitements, non ?

Maintenant, une question plus basique risque d’entraver l’intérêt d’un cache :
ça nécessite à chaque fois des locks, et donc ça peut perdre rapidement son intérêt si c’est mal utlisé…

.Gilles

2010/8/26 Fil <fil@rezo.net>

C’est juste une question de performance pure :

  • Il semble déjà qu’il soit plus rapide d’accéder à MySQL via socket que par IP. Je n’ai pas trouvé où ça se paramétrait…
    cf. http://www.mysqlperformanceblog.com/2006/08/09/cache-performance-comparison/
  • Les caches proches de PHP retournent des résultats plus rapidement que le cache mysql
  • Surtout on peut stocker les résultat de requêtes très lourdes sans effort supplémentaire
  • Actuellement on ne fait que des requêtes atomiques, sans utiliser de transaction SQL. ça permettrait j’ajouter cette notion dans le code, et de diminuer le nombre de requêtes dans le cas où un grand nombre de requêtes imbriquées servent à générer des IN en cascade.

L’intérêt, je le vois surtout dans ces deux dernier cas.

D’autres CMS le font déjà, il doit y avoir des raisons pratiques là dessous :
cf. le cache APC pour WP: http://markjaquith.wordpress.com/2010/08/06/apc-object-cache-backend-for-wordpress/

.Gilles

C’est juste une question de performance pure :

il suffit d’indiquer le path vers mysql.sock à la place du host dans la connexion pour utiliser le socket au lieu d’IP

  • Les caches proches de PHP retournent des résultats plus rapidement que le cache mysql
  • Surtout on peut stocker les résultat de requêtes très lourdes sans effort supplémentaire
  • Actuellement on ne fait que des requêtes atomiques, sans utiliser de transaction SQL. ça permettrait j’ajouter cette notion dans le code, et de diminuer le nombre de requêtes dans le cas où un grand nombre de requêtes imbriquées servent à générer des IN en cascade.

L’intérêt, je le vois surtout dans ces deux dernier cas.

Faut pas oublier qu’on a déjà un cache dans SPIP, de plus haut niveau, qui inclue implicitement le résultat des requêtes.
L’utiliser a bon escient répond à 99% des besoins.
Autrement dit, il est souvent pertinent de remplacer un script php appelé en direct qui rejoue la requete sans cache, par un squelette SPIP qui appelle le php sous forme de script, avec les paramètres d’env pertinent, et qui stocke donc le résultat en cache.
C’est encore plus près de la sortie que les caches niveau PHP, et ça profite de tous les mécanismes existants.

D’autres CMS le font déjà, il doit y avoir des raisons pratiques là dessous :
cf. le cache APC pour WP: http://markjaquith.wordpress.com/2010/08/06/apc-object-cache-backend-for-wordpress/

L’absence de cache de plus haut niveau est une bonne raison, pour éviter d’écrouler le serveur SQL.

Cédric

2010/8/27 cedric.morin@yterium.com <cedric.morin@yterium.com>

C’est juste une question de performance pure :

il suffit d’indiquer le path vers mysql.sock à la place du host dans la connexion pour utiliser le socket au lieu d’IP

Ok

  • Les caches proches de PHP retournent des résultats plus rapidement que le cache mysql
  • Surtout on peut stocker les résultat de requêtes très lourdes sans effort supplémentaire
  • Actuellement on ne fait que des requêtes atomiques, sans utiliser de transaction SQL. ça permettrait j’ajouter cette notion dans le code, et de diminuer le nombre de requêtes dans le cas où un grand nombre de requêtes imbriquées servent à générer des IN en cascade.

L’intérêt, je le vois surtout dans ces deux dernier cas.

Faut pas oublier qu’on a déjà un cache dans SPIP, de plus haut niveau, qui inclue implicitement le résultat des requêtes.
L’utiliser a bon escient répond à 99% des besoins.
Autrement dit, il est souvent pertinent de remplacer un script php appelé en direct qui rejoue la requete sans cache, par un squelette SPIP qui appelle le php sous forme de script, avec les paramètres d’env pertinent, et qui stocke donc le résultat en cache.
C’est encore plus près de la sortie que les caches niveau PHP, et ça profite de tous les mécanismes existants.

Effectivement, j’avais oublié que Fastcache (c’est bien de lui que tu parles ?) peut ne mettre en cache statique que certains squelettes. Effectivement, c’est la solution optimale. Je pense qu’avec lui, il est inutile de se lancer dans des développements qui seraient complètement redondants.

D’autres CMS le font déjà, il doit y avoir des raisons pratiques là dessous :
cf. le cache APC pour WP: http://markjaquith.wordpress.com/2010/08/06/apc-object-cache-backend-for-wordpress/

L’absence de cache de plus haut niveau est une bonne raison, pour éviter d’écrouler le serveur SQL.

Tu veux dire la présence de cache statique, c’est cela ?

.Gilles

Effectivement, j'avais oublié que Fastcache (c'est bien de lui que tu parles
?) peut ne mettre en cache statique que certains squelettes.

Hein mais non, ça n'a rien à voir, fastcache met en cache des pages
complètes, là où tu parlais de mettre en cache le résultat de requêtes
SQL. Le cache normal de SPIP est en effet plus proche de ce que tu
souhaites, mais il manque de maniabilité je trouve, par exemple pour
dire "cacher ce résultat aussi longtemps que possible, indépendamment
de tout var_mode ou autre". Et il n'est pas exploitable en "pur php"
sans passer par des squelettes. Mais la fonction cache_me() du plugin
memoization répond à ce dernier point avec brio : il faudrait
commencer à l'utiliser :slight_smile:

-- Fil