[spip-dev] [proposition] optimisation de l'indexation

Bonjour,

En jetant un oeil au fichier ecrire/data/.index, je trouve ceci :
article 170 1
article 171 1
article 172 1
syndic 40 1
syndic 13 1
auteur 136 1
mot 119
article 174
mot 119
article 175
auteur 138 1
mot 120 1
article 176 1
article 176
article 176 1
article 176 1
article 176
article 176 1
article 176 1
article 176 1
article 176

Je pense qu'en utilisant une table, ça permettra automatiquement d'éviter de
réindexer plusieurs fois le même objet :

Pour éviter une boucle et un champ par type d'objet ("factorisation"), je
propose une table "Index_Objet" comme celle-là :

Type
Id
Date

La clé primaire étant formée de Type et Id.

Une autre proposition "ergonomique" :
Afficher l'état de l'index :
On se sert du fichier .index actuel (ou de la table) et on indique le nombre
d'objets à réindexer par rapport au nombre total.
(on peut le faire aussi en % et/ou graphiquement).

Eventuellement, on peut à la demande afficher la liste des objets avec
pourquoi pas un bouton qui force la réindexation immédiate d'un article.

Cordialement,

Yves

L'idée est de NE PAS se connecter à la base quand on veut juste signaler
qu'un article a été lu. Et on ne réindexe jamais un objet déjà indexé :wink:

-- Fil

@ Yves Pratter <yves.pratter@laposte.net> :

Ok, si je te comprends bien, le code ne réindexe pas pour rien.

Mais ce que j'ai constaté, c'est qu'il faut "un moment" pour vider le
fichier .index et si une page non encore indexée est à la fin du fichier,
son indexation sera "retardée".

(Quand je fais un refresh avec mon navigateur de la page d'accueil par
exemple, une seule ligne du fichier est traitée à la fois).

Yves

Ok, si je te comprends bien, le code ne réindexe pas pour rien.

oui

Mais ce que j'ai constaté, c'est qu'il faut "un moment" pour vider le
fichier .index et si une page non encore indexée est à la fin du fichier,
son indexation sera "retardée".

exact

(Quand je fais un refresh avec mon navigateur de la page d'accueil par
exemple, une seule ligne du fichier est traitée à la fois).

oui

Je pense que ça n'est pas gênant en utilisation normale. Par contre si tu
modifies 2500 articles sur un site qui a un trafic presque nul, ça risque de
prendre un peu de temps...

-- Fil

Je pense que ça n'est pas gênant en utilisation normale. Par contre si tu
modifies 2500 articles sur un site qui a un trafic presque nul, ça risque

de

prendre un peu de temps...

C'est exactement mon cas : site de test.
et je n'ai pas besoin d'avoir 2500 articles pour avoir une centaine de
lignes dans le fichier.

Ok, si je te comprends bien, le code ne réindexe pas pour rien.

oui

Mais ce que j'ai constaté, c'est qu'il faut "un moment" pour vider le
fichier .index et si une page non encore indexée est à la fin du fichier,
son indexation sera "retardée".

exact

(Quand je fais un refresh avec mon navigateur de la page d'accueil par
exemple, une seule ligne du fichier est traitée à la fois).

oui

Sauf erreur, c'est le cas du code que j'ai envoyé mais pas du code CVS:
dans le cas d'un doublon dans le fichier .index, le code actuel
s'aperçoit que c'est déjà indexé et du coup ne fait rien du tout, alors que
l'idée est de faire une indexation à chaque connexion au serveur.

Je pense que ça n'est pas gênant en utilisation normale. Par contre si tu
modifies 2500 articles sur un site qui a un trafic presque nul, ça risque de
prendre un peu de temps...

Le pb se pose surtout quand on réinstalle une base de données sauvegardée:
comme la sauvegarde ne s'encombre pas, et ça se comprend, des index, le moteur
de recherche est pratiquement inopérant pendant un bon moment.

esj

      Emmanuel

Sauf erreur, c'est le cas du code que j'ai envoyé

Excuse-moi, mais je ne sais pas à quoi tu fais référence.

mais pas du code CVS: dans le cas d'un doublon dans le fichier .index, le
code actuel s'aperçoit que c'est déjà indexé et du coup ne fait rien du
tout, alors que l'idée est de faire une indexation à chaque connexion au
serveur.

Non, pas obligatoirement "à chaque connexion".

Le pb se pose surtout quand on réinstalle une base de données sauvegardée:
comme la sauvegarde ne s'encombre pas, et ça se comprend, des index, le
moteur de recherche est pratiquement inopérant pendant un bon moment.

Certains préconiseraient plutôt de faire un script qui indexe à mort, et de
l'appeler... c'est assez élémentaire à faire en recopiant la partie ad hoc
de inc-public-global (bon, c'est vrai qu'il faut savoir que c'est là...
d'ailleurs je vais le déplacer, pour le coup, dans inc_index...)

<?php
    include("inc.php3");
    echo "j'indexe &agrave; mort";

            include_ecrire("inc_texte.php3");
            include_ecrire("inc_filtres.php3");
            include_ecrire("inc_index.php3");

            while ($s = sizeof($suite = file($fichier_index))) {
                $s = $suite[$n = rand(0, $s)];
                unset($suite[$n]);
                $f = fopen($fichier_index, 'wb');
                fwrite($f, join("", $suite));
                fclose($f);
                $s = explode(' ', trim($s));
                indexer_objet($s[0], $s[1], $s[2]);
            }
                                                       
    }
?>

PS: ton email passe mal chez moi et dans les archives ?

-- Fil

Excuse-moi, mais je ne sais pas à quoi tu fais référence.

Oups, je l'avais rédigé entre la poire et le fromage et ça n'est pas parti:

on peut déà éliminer les doublons
(qui sont dus aux "recalculer cette page")
en remplaçant dans inc-public-global l'accolade qui suit la ligne
  if (timeout('indexation'))
par:

  if ($s = sizeof($suite = array_unique(file($fichier_index)))) {
                                 include_ecrire("inc_texte.php3");
                                 include_ecrire("inc_filtres.php3");
                                 include_ecrire("inc_index.php3");
                                 while ($suite)
                                   {
                                     $s = array_shift($suite);
                                     $e = explode(' ', trim($s));
                                     if ($e[1] AND ($e[2] OR (!deja_indexe($e[0],
  $e[1]))))
                                       {
                                         indexer_objet($e[0], $e[1]);
                                         break;
                                       } }
                                 $f = fopen($fichier_index, 'wb');
                                 fwrite($f, join("", $suite));
                                 fclose($f);

ca limite déjà un peu les calculs inutiles.

esj

                                    $s = array_shift($suite);

ne marche pas en php3 (pas encore abandonné)

par ailleurs deux processus concurrents risquent d'indexer le même objet en
même temps (d'où l'intérêt du random)

-- Fil

??? Ca diminue le risque mais ne le supprime pas,
et ça n'indexe pas le plus ancien, c'est dommage.
Je suis d'accord avec Yves qu'il faut passer par MySQL
pour éviter ça (ou alors un lock Posix).
Je n'ai d'ailleurs pas compris pourquoi tu disais
qu'on veut éviter de passer par la base:
le prédicat "déja_indexe" le fait bien.

esj

>deux processus concurrents risquent d'indexer le même objet en
>même temps (d'où l'intérêt du random)

??? Ca diminue le risque mais ne le supprime pas,

certes

et ça n'indexe pas le plus ancien, c'est dommage.

pourquoi ? c'est égal...

Je suis d'accord avec Yves qu'il faut passer par MySQL
pour éviter ça (ou alors un lock Posix).
Je n'ai d'ailleurs pas compris pourquoi tu disais
qu'on veut éviter de passer par la base:
le prédicat "déja_indexe" le fait bien.

deja_indexe() n'est "vrai" que APRES l'indexation de l'objet, pas pendant
qu'elle se fait

-- Fil

et ça n'indexe pas le plus ancien, c'est dommage.

pourquoi ? c'est égal...

Quand on publie 2 articles, on s'attend à ce que le 1er
soit indexé avant le 2e, autrement on se demande s'il
n'y a pas un bug au niveau du 1er.

Je suis d'accord avec Yves qu'il faut passer par MySQL
pour éviter ça (ou alors un lock Posix).
Je n'ai d'ailleurs pas compris pourquoi tu disais
qu'on veut éviter de passer par la base:
le prédicat "déja_indexe" le fait bien.

deja_indexe() n'est "vrai" que APRES l'indexation de l'objet, pas pendant
qu'elle se fait

Ah ok, je croyais que tu voulais éviter toute connexion à MySQL (cf le db_ok).
Mais de nouveau ça pose le pb de l'accès concurrent: il faut donc vraiment
supprimer les doublons dans .index (tant pis pour php3, ou écrire array_unique).

"Déesse A." <esj@vertsdesevres.net> a écrit dans le message de

news:A36DB9CA-1FA5-11D8-99B7-003065B575A8@vertsdesevres.net...

Quand on publie 2 articles, on s'attend à ce que le 1er
soit indexé avant le 2e, autrement on se demande s'il
n'y a pas un bug au niveau du 1er.

Je suis d'accord avec toi, c'est vraiment troublant !

J'ai regardé dans mon coin comment fonctionnait l'indexation (et je n'ai pas
vue la boucle "j'index à mort" de Fil :wink: ) :
Je me suis donc fait un bout de code qui reprend le code original :
Il montre le sentiment d'indexation "aléatoire". Il y a en effet un (petit)
bug, le random pointe parfois à la fin du fichier et n'indexe donc rien !

    $s = $suite[$n = rand(0, $nb)];

il faut mettre :
    $s = $suite[$n = rand(0, $nb-1)];

Une idée, adapter ce code pour le lancer périodiquement avec un cron ou
depuis la ligne de commande (.sh ou .bat)

Yves

begin 666 testindex.php
M/#]P:' -"FAE861E<B@B0V]N=&5N="U4>7!E.B!T97AT+W!L86EN(BD[#0H-
M"@T*:6YC;'5D92@B:6YC7W9E<G-I;VXN<&AP,R(I.PT*#0H))&9I8VAI97)?
M:6YD97@@/2 D2%144%]315)615)?5D%24ULB1$]#54U%3E1?4D]/5")=+B<O
M96-R:7)E+V1A=&$O+FEN9&5X)SL-"B\O"21F:6-H:65R7VEN9&5X(#T@)V5C
M<FER92]D871A+RYI;F1E>"<[#0H@(" @(" @(&5C:&\@(F]U=F5R='5R92 B
M("X@)&9I8VAI97)?:6YD97@@+B B7&XB.PT*#0H):68@*&9I;&5?97AI<W1S
M*"1F:6-H:65R7VEN9&5X*2D@>PT*(" @(" @(" @(" @(" @(" @(" @(" @
M96-H;R D9FEC:&EE<E]I;F1E>"XB(&5X:7-T95QN(CL-"@D)"6EF("@D;F(@
M/2!S:7IE;V8H)'-U:71E(#T@9FEL92@D9FEC:&EE<E]I;F1E>"DI*2!["@D)
M"0DO+VEN8VQU9&4H(FEN8U]T97AT92YP:' S(BD["@D)"0DO+VEN8VQU9&4H
M(FEN8U]F:6QT<F5S+G!H<#,B*3L*"0D)"6EN8VQU9&4H(FEN8U]I;F1E>"YP
M:' S(BD["@H@(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @("\O(&EL
M(&9A=70@8F]U8VQE<@H)"0D))',@/2 D<W5I=&5;)&X@/2!R86YD*# L("1N
M8BTQ*5T["@H@(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(&5C:&\@
M(DQE8W1U<F4@;&EG;F4@(BXD;BXB+R(N)&YB+B)<;B(["B @(" @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @96-H;R B26YD97AA=&EO;B!O8FIE=" B
M+B1S+B)<;B(["@H)"0D)=6YS970H)'-U:71E6R1N72D["@D)"0DD9B ](&9O
M<&5N*"1F:6-H:65R7VEN9&5X+" G=V(G*3L*"0D)"69W<FET92@D9BP@:F]I
M;B@B(BP@)'-U:71E*2D["@D)"0EF8VQO<V4H)&8I.PH)"0D))',@/2!E>'!L
M;V1E*"<@)RP@=')I;2@D<RDI.PH)"0D):6YD97AE<E]O8FIE="@D<ULP72P@
M)'-;,5TL("1S6S)=*3L*"0D)?0H)"0EE;'-E($!U;FQI;FLH)&9I8VAI97)?
1:6YD97@I.PH)?0H_/@T*#0H`
`
end