Les déchets transitoires sont-ils collectés?
-
-
théoriquement,ils devraient être supprimés lors de l'exécution de cron (s'ils sontexpirés)theoretically they should be removed when cron is run (if they are expired)
- 0
- 2011-01-09
- onetrickpony
-
@Ambitious Amoeba Jene vois rien avec cettefonctionnalité accrochée à cron.C'estpourquoije pose la question - cela semble être une hypothèse dontje ne suispas sûr qu'elle soit valide.@Ambitious Amoeba I do not see anything with that functionality hooked to cron. That is why I am asking - it seems to be an assumption I am not sure is valid.
- 0
- 2011-01-09
- Rarst
-
Je crois comprendre que lestransitoiresne sontpas vraiment de vraisprocessus cron,ilsnécessitent aumoins que quelqu'un demande unepagepour qu'ils soient créés/supprimés (mais c'est lameilleure chose àfairepour un vraiprocessus cron).Jen'aipas surveillémestransitoires,voyez-vous destransitoirestraîner souvent après l'expiration?It's my understanding that transients are not really real cron processes, they at least require someone to request a page in order for them to be created/removed(but it's the next best thing to a real cron process). I've not monitored my transients, are you seeing transients hang around often after expiry?
- 0
- 2011-01-09
- t31os
-
@t31os ouije les vois suspendus,maisje n'ai aucuneinformation sur la duréependant laquelleilspeuvent être suspendus avant que l'onpuisse dire définitivement qu'ilsne sontpas ramassés@t31os yes I do see them hanging, but I have no information on how long they can hang before it can be said definitively that they are not garbage collected
- 0
- 2011-01-09
- Rarst
-
@Rarst - Jene saispasnonplus comment lenettoyageest déterminé,voyez-vous ceproblème avec destransitoiresparticuliers ou desproblèmes différents?@Rarst - I'm not sure how cleanup is determined either, are you seeing this problem with any particular transients or differing ones?
- 0
- 2011-01-09
- t31os
-
@t31os Jene vaispasperdre detemps à coder desengins dejournalisation destransitoires avant de savoir s'ils sont censés être ramassés dutout.:)@t31os I am not going to waste time on coding transients logging contraption before I know if they are supposed to be garbage collected at all. :)
- 0
- 2011-01-09
- Rarst
-
@Rarst - Beatsme mate,je voulaisjustepartager quelques réflexions .. :)@Rarst - Beats me mate, just wanted to share a few thoughts.. :)
- 0
- 2011-01-09
- t31os
-
il semble que lestransitoiresexpirés soient supprimés lorsque `get_transient` se déclenche - http://core.trac.wordpress.org/browser/tags/3.0.4/wp-includes/functions.php#L721it seems that expired transients are deleted when `get_transient` fires off - http://core.trac.wordpress.org/browser/tags/3.0.4/wp-includes/functions.php#L721
- 0
- 2011-01-09
- onetrickpony
-
Vousne devriez doncpas voir detransitoiresexpirés dans labase de données,sauf si quelque chose s'estmalpassé avec delete_option ()So you shouldn't see any expired transients in the db, unless something went wrong with delete_option()
- 0
- 2011-01-09
- onetrickpony
-
@Ambitious Amoeba ouais,j'ai unpeumentionné celaen question.Monpointest - la créationtransitoirene supposeni negarantit qu'elle serajamais demandée.Mettre l'accent sur la question d'origine - ** quandet si letransitoireexpiréest supprimé sije ne le _get_jamais? **@Ambitious Amoeba yeah, I kinda mentioned that in question. My point is - transient being created doesn't assume or guarantee that it is ever going to be requested. Stressing the original question - **when and if expired transient gets deleted if I never _get_ it?**
- 1
- 2011-01-09
- Rarst
-
mais quelest l'intérêt d'utiliser destransitoires alors?but what's the point of using transients then?
- 0
- 2011-01-09
- onetrickpony
-
@Ambitious Amoeba lefaitest que lestransitoires sont unmécanisme demiseen cache.Le concept de cache suppose que les donnéesexpirentet ne supposepas de succèsgarantis.Si le cachene nettoiepas les donnéesexpirées,il y a unefuite de ressources.@Ambitious Amoeba the point is that transients are caching mechanism. Cache concept assumes expiring data and doesn't assume guaranteed hits. If cache doesn't cleanup expired data then it is leaking resources.
- 0
- 2011-01-09
- Rarst
-
cela suppose que vousnettoyez les donnéesexpirées,mais oui,vous avez raison,il y a des situations dans lesquellesellesne seraientjamais supprimées.Comme supprimer un widget qui utilise destransitoires.Vous devez soumettre unticket sur letracpour cela :)it asssumes you clean up the expired data, but yes, you're right, there are situations in which it would never get deleted. Like removing a widget which uses transients. You should submit a ticket on the trac for this :)
- 1
- 2011-01-09
- onetrickpony
-
@Rarst - Cela semble être une choseparfaitepour écrire unpatchet le soumettre àtrac?@Rarst - Sounds like a perfect thing to write a patch for and submit to trac?
- 1
- 2011-01-09
- MikeSchinkel
-
@MikeSchinkel yeaaaah ... après que quelqu'un réponde définitivement si desfoutustransitoires sont (ou sont censés être) ramassés :)@MikeSchinkel yeaaaah... after someone answers definitively at last if damn transients are (or are supposed to be supposed to be) garbage collected :)
- 0
- 2011-01-09
- Rarst
-
@Rarst - Le seulmoyen de lui dire avec certitude detracer le code ...@Rarst - The only way to tell for sure it to trace through the code...
- 0
- 2011-01-10
- MikeSchinkel
-
Ilsn'ontpasbesoin d'être «ramassés».Si vousne les récupérezjamais,peuimporte qu'ils soient là ounon.They don't need to be "garbage collected". If you never fetch them, then it doesn't matter if they're there or not.
- 0
- 2011-09-12
- Otto
-
@Otto si vous commencez à avoir ** des dizaines demilliers ** detellesentrées de déchets dans latable des options (ce quipeut arriveret seproduit dans lapratique,voir la question liée) Jepense que c'est assezimportant,non?@Otto if you start to have **tens of thousands** of such garbage entries in options table (which can and does happen in practice, see linked question) I think it quite matters, no?
- 0
- 2011-09-12
- Rarst
-
Non,vraimentpas.Lesbases de donnéespeuvent contenir desmillionset desmillions de lignes sans ralentissementnotable.Cela s'appelle «indexation»,et cela reste rapidemême avecbeaucoup de lignes: http://en.wikipedia.org/wiki/Index_(database). Deplus,appeler le SQL DELETE sureuxne les supprimepas réellement de labase de données.Il les supprime simplement de l'index,jusqu'à ce que vousfassiez également un OPTIMIZE TABLE sur latable,ce quiest une opération de longue durée.Iln'estgénéralementpasnécessaire de «nettoyer» lesenregistrements dans unebase de données.Laissez labase de donnéesfaire sontravail.C'estmeilleur que vous.No, it really doesn't. Databases can have millions and millions of rows in them without appreciable slowdown. It's called "indexing", and it stays fast as heck even with lots and lots of rows: http://en.wikipedia.org/wiki/Index_(database). What's more, calling the SQL DELETE on them doesn't actually delete them from the database. It just removes them from the index, until you do an OPTIMIZE TABLE on the table as well, which is a long running operation. There is generally no need to "clean up" records in a database. Let the database do its job. It's better at it than you are.
- 0
- 2011-09-12
- Otto
-
Pour êtreplusprécis à ce sujet,vous remarquerezpeut-être que lestransitoires dans labase de données ont leurindicateur de chargement automatiquemis à "no",ce qui signifie qu'ilsne sontpas chargés au démarrage.Leprincipal ralentissement detoute requête debase de donnéesest letransfert de données réel de labase de données vers leprogramme.Les requêteselles-mêmes,sielles sont écrites correctementet correctementindexées (ce qui signifie que la requêtene provoquepas d'analyse detable),ne prennentpratiquementpas detempsen comparaison.Peuimporte si vous avez 100enregistrements ou 100 000,carfaire un simple SELECT sur un champindexéest une opération O (log (n)).Celane changepas vraimentjusqu'à ce que vous obteniezplus d'unmillion d'enregistrements.To be more specific about it, you may notice that transients in the database have their autoload flag set to "no" which means they don't get loaded on startup. The primary slowdown from any database query is the actual data transfer from the database to the program. Queries themselves, if written correctly and properly indexed (meaning the query doesn't cause a table scan), take virtually no time by comparison. Doesn't matter if you have 100 records or 100,000, as doing a simple SELECT on an indexed field is an O(log(n)) operation. This doesn't really change until you get 1M+ records or so.
- 0
- 2011-09-12
- Otto
-
@Otto Pourriez-vous s'il vousplaît déplacer ceci vers une réponse afin que lesinformations soientplus visibles?Jene prétendspas qu'ilfaudrabeaucoup d'entrées de déchetspourgâcher les choses ... Mais si quelque chosefuit des ressources (ce qui seproduitfacilement avec lestransitoires carils ont une limite de longueur de clé quin'estpas vérifiée,ilestfacile d'engénérer untéléchargementetne touchezplusjamaisparce que la cléest cassée),alorstôt outard,celagâchera les choses.Jene criepas "réparer ceci dans lenoyau",maisje ne voispasnonplus lenettoyage commeinutile.@Otto Could you please move this to an answer so information is more visible? I do not argue that it will take a lot of garbage entries to screw things up... But if anything is leaking resources (which easily happen with transients because they have key length limit that is not checked, easy to generate crapload of them and never touch again because key is broken) then sooner or later it will screw things up. I am not screaming "fix this in core", but I don't see cleanup as useless either.
- 0
- 2011-09-12
- Rarst
-
«Fous les choses»est unpeu une déclaration vague.Lemieux queje puisse voir,c'est que labase de données devienttrop volumineusepour unespace de compte limité.Ilne cassera rientant qu'ilne deviendrapas vraimenttrès,trèsgrand.Jetravaille avec destables contenant 20millions d'enregistrements.Leur rechercheest unpeu lente,maispas sans raison.Vous avez raison àpropos de la limite de longueur de clé,mais 45 caractères suffisentpourtous les cas réalistes auxquelsje peuxpenser.D'accord,bien sûr,ilestpossible defaire quelque chose defou,mais cela arrive-t-il souvent?On dirait que l'auteur duplugin devrait êtrenotifié au lieu d'une solution de contournement ..."Screw things up" is a bit of a vague statement. The most that I can see happening is that the database gets too large for a limited account space. It's not going to actually break anything until it gets very, very large indeed. I work with tables that have 20 million records in them. Searching them is a bit slow, but not unreasonably so. You're correct about the key length limit, but 45 chars is plenty for every realistic case I can think of. Okay, sure, it's possible to do something crazy, but does that happen often? Seems like plugin author should be notified instead of a workaround...
- 0
- 2011-09-12
- Otto
-
@Otto "pas souvent"et "jamais" sont des choses différentes.Sij'arrive à créer unplugin àpartir de cela,je prévois d'ajouter également un avertissementpour la longueur de la clé.Cependant,je ne voispas l'intérêt de conserver les donnéesinutiles dans labase de données simplementparce que celafonctionne demanièretransitoire.Cen'estpeut-êtrepas unbogue,mais cen'estguère unefonctionnalité.@Otto "not often" and "never" are different things. If I get to making plugin out of this I plan to add warning for key length as well. However I do not see a point in keeping garbage data in database just because transient work that way. It may not be a bug, but it is hardly a feature.
- 0
- 2011-09-12
- Rarst
-
Monpointn'estpas de lesgarder dans labase de données simplementparce qu'ilsfonctionnent de cettefaçon.Ce queje veux dire,c'est qu'essayer de «ramasser les ordures» coûteplus cher qu'iln'en économise,danspratiquementtous les cas.C'esten fait contre-productif.My point isn't to keep them in the database just because they work that way. My point is that trying to "garbage collect" them costs more than it saves, in virtually all cases. It's actually counterproductive.
- 0
- 2011-09-12
- Otto
-
Ticket detrac associé: http://core.trac.wordpress.org/ticket/20316Related trac ticket: http://core.trac.wordpress.org/ticket/20316
- 1
- 2013-09-29
- Stephen Harris
-
3 réponses
- votes
-
- 2011-01-10
Ils le sontmaintenant
Àpartir de WordPress 3.7,lestransitoiresexpirés sont supprimés lors desmises àniveau de labase de données,voir # 20316
Ancienne réponse
Si quelqu'unne peutpasme montrer le contraire,il semble que lestransitoiresne soientpas récupérés aprèstout. Ce quiestpire,c'est que contrairement aux options,ellesne sontpasgaranties d'être stockées dans labase de données. Iln'y a donc aucunmoyenfiable de récupérer la liste detous lestransitoirespour vérifier leurexpiration.
add_action( 'wp_scheduled_delete', 'delete_expired_db_transients' ); function delete_expired_db_transients() { global $wpdb, $_wp_using_ext_object_cache; if( $_wp_using_ext_object_cache ) return; $time = isset ( $_SERVER['REQUEST_TIME'] ) ? (int)$_SERVER['REQUEST_TIME'] : time() ; $expired = $wpdb->get_col( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout%' AND option_value < {$time};" ); foreach( $expired as $transient ) { $key = str_replace('_transient_timeout_', '', $transient); delete_transient($key); } }
They now are
Starting with WordPress 3.7 expired transients are deleted on database upgrades, see #20316
Old answer
If someone can't show me otherwise it seems that transients are not garbage collected after all. What makes it worse is that unlike options they are not guaranteed to be stored in database. So there is no reliable way to fetch list of all transients to check them for expiration.
Some makeshift code to do garbage collection if database is used for storage:
add_action( 'wp_scheduled_delete', 'delete_expired_db_transients' ); function delete_expired_db_transients() { global $wpdb, $_wp_using_ext_object_cache; if( $_wp_using_ext_object_cache ) return; $time = isset ( $_SERVER['REQUEST_TIME'] ) ? (int)$_SERVER['REQUEST_TIME'] : time() ; $expired = $wpdb->get_col( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout%' AND option_value < {$time};" ); foreach( $expired as $transient ) { $key = str_replace('_transient_timeout_', '', $transient); delete_transient($key); } }
-
$time=$ _SERVER ['REQUEST_TIME'];puisen utilisant $time dans la requête SQL -ne faitespas cela.Traitezplus attentivement les variables/valeurs $ _SERVERpour éviter lesinjections SQL.$time = $_SERVER['REQUEST_TIME']; and then making use of $time in the SQL query - don't do that. Deal more carefully with $_SERVER variables / values to prevent SQL injections.
- 0
- 2011-01-10
- hakre
-
@hakre hm ... J'ai choisi cela dans uneprésentation sur lesperformances de PHP qui recommandait dene pas utiliser `time ()`,ce quipeut causer desbogues (l'exécutionn'estpasinstantanéeparnature).L'heure de la demandeest définiepar PHP lui-mêmeet neprovient d'aucuntype de donnéesfourniespar l'utilisateur.Pourquoi cette vulnérabilité?@hakre hm... I picked that from presentation on PHP performance that recommended it over using `time()` which can cause bugs (execution is not instant by nature). Request time is being set by PHP itself, doesn't come from any kind of user-supplied data. Why is this vulnerability?
- 0
- 2011-01-10
- Rarst
-
@Rarst: Jen'aipas dit que vousne devriezpas l'utiliser,vous devez simplement vous assurer qu'ilestencodéen toute sécuritépour être utilisé dans la requête SQL.Vous devez lefaire avec chaque variable d'une sourceexterne.Les variables $ _SERVERpeuventne pas être définies commeprévu,maismême définiespar l'utilisateur demandeur.Je voulais seulementpropager debonnespratiques de codage.Commetoujours,pouren savoirplus sur l'état réel de la disponibilité,consultez la documentation.Pour PHP 4parexemple,unetelle variablen'existepaset pourrait être écraséepar unen-têtepersonnalisé ou une variable d'environnement - http://php.net/manual/en/reserved.variables.server.php@Rarst: I didn't say that you should not use it, you should just ensure that it is safely encoded to be used inside the SQL query. You should do this with every variable from an external source. $_SERVER variables might not be set as expected, and instead, set by the requesting user even. I only wanted to propagate some good coding practice. As always, to learn about the real state of availability, see the docs. For PHP 4 for example, such a variable does not exists and might be overwritten by a custom header or environment variable - http://php.net/manual/en/reserved.variables.server.php
- 0
- 2011-01-10
- hakre
-
@hakre corrigé (jepense),mercipour le rappel PHP4btw (j'ai hâte que WordPress abandonne le support)@hakre fixed (I think), thanks for PHP4 reminder btw (I can't wait for WordPress to drop support of it)
- 0
- 2011-01-10
- Rarst
-
Cela a l'airbeaucoupmieux àmes yeux;).Espérons qu'iln'y ait aucunproblème avectime ()et lesentiersnégatifs quipourraient supprimertout oupas detransitoires quepar accident.Nefaitesjamais confiance à un systèmeen cours d'exécution: PThat looks much better in my eyes ;). Let's hope that there is no problem with time() and negative integers that might delete all or no transients than by accident. Never trust a running system :P
- 0
- 2011-01-10
- hakre
-
Au cas où vousne le sauriezpas,_est un caractèregénérique uniquepour lesinstructions LIKEet devraitidéalement être échappé.:)In case you weren't aware, _ is a single char wildcard for LIKE statements, and should ideally be escaped. :)
- 0
- 2011-01-10
- Denis de Bernardy
-
@Denis ouais,je le sais ... Maispas de différencepratique dans cette requête? .. Amoins que quelqu'unn'arrive ànommer l'option XtransientXtimeoutX ou quelque chose.@Denis yeah, I know that... But no practical difference in this query?.. Unless someone manages to name option XtransientXtimeoutX or something.
- 0
- 2011-01-10
- Rarst
-
N'utiliseriez-vouspas $ wpdb->prepare ()pour vousprotéger correctement des données corrompues comme ce dontparlait @hakre?Cela résoudrait également l'échappement du '_'.Je recommanderais de l'utiliser,commemeilleurepratique.Wouldn't you use $wpdb->prepare() in order to properly protect yourself from tainted data such as what @hakre was talking about? This would also solve the escaping of the '_' as well. I'd recommend using it, as a best practice.
- 0
- 2012-06-22
- Tom Auger
-
@Tom autre que "pour être vraiment vraiment sûr",cette requête spécifiquen'apas vraimentbesoin d'êtrepréparéeet jen'aipaspris lapeine de l'ajouter.@Tom other than "to be really really sure" this specific query doesn't really need prepare and I didn't bother to add it.
- 0
- 2012-06-22
- Rarst
-
Vous êtesen cemoment queje la regarde.Le (int)estprobablementtoute laprotection dont vous avezbesoin sur cette variable serveur.You're right now that I look at it. The (int) probably is all the protection you need on that server variable.
- 0
- 2012-06-22
- Tom Auger
-
Ne devrait-ilpas être `_transient_timeout_%`?Justepour vous assurer que c'est vraiment ce que WP utilise commepréfixe?;)Shouldn't it be `_transient_timeout_%`? Just to make sure it really is what WP uses as prefix? ;)
- 0
- 2013-07-28
- kaiser
-
- 2011-09-12
Transférer certains des commentaires de la discussion vers une réponse,avec reformulationet reformatage ..
Engros,cela revient à dire qu'àmoins d'avoir un cas superextrême,ilsn'ontpas vraimentbesoin d'être "ramassés". Si vousne les récupérezjamais,peuimporte sielles sont là ounon.
Voir,lestransitoires sont stockés dans letableau des optionspar défaut. Dans uneinstallation debase,letableau des options contiendrapeut-être 100entrées. Chaquetransitoire ajoute deuxentrées supplémentaires,maismême si vousen avez desmilliers,ellesn'affectentpas la vitesse du site,carellesne sontpas chargées automatiquement.
Au démarrage,WordPress charge les optionsen mémoire,maisilne charge que les options dont l'indicateur de chargement automatiqueest activé. Lestransitoiresne comprennentpas celaet ne sont doncpas chargésen mémoire. Seuls lestransitoires qui sonteffectivement utilisésplustardentraîneront un coût.
Dupoint de vue de labase de données,latable des options a desindex à lafois sur l'ID d'optionet lenom de l'option. Lestransitoires sonttoujours chargésen fonction dunom (clé),et donc les recherchespoureux sonttoujours des sélections simples sur une seule valeur de clé unique. Ainsi,la rechercheest O (log (n))et est super rapide. Avec un Big-O de log (n),vous devrezentrer dans lesmillionset lesmillions de lignes avant que celane devienneperceptible. Franchement,lesfraisgénéraux liés à la configurationet au démontage de la requête,ainsi que letransfert de données réel,sontbeaucoupplus longs. La requêteelle-même s'exécuteessentiellementen temps zéropar comparaison. Donc,simplement avoir lignesinutilisées supplémentairesn'affecte rien d'autre que l'utilisation d'espace disque supplémentaire.
L'indexation dans lesbases de donnéesfaitpartie de cesidéestrès lues quin'ont aucun senspour lespersonnes quin'ontpas vraiment compris ce qui sepasse dans les coulisses. Lesbases de données sont conçuespour une récupération rapide des données,de A à Z,et peuventgérer cegenre de choses sansproblème. C'est une assezbonne lecture: http://en.wikipedia.org/wiki/Index_(database )
Maintenant,lenettoyage de lamanière laplus évidente (appeler SQL DELETE sureux)ne les supprimepas réellement de labase de données. Il les supprime simplement de l'indexet marque la ligne comme "supprimée". Encore unefois,c'est ainsi quefonctionnent lesbases de données. Pour réellement libérer de l'espace disque,vous devezensuite continueret faire un OPTIMIZE TABLEpar la suite,et cen'estpas une opération rapide. Çaprend dutemps. Probablementplus detemps que çane vaut. Cen'estprobablementpas suffisantpour vouspermettre d'économiser dutemps CPU,autotal.
Si vous avez un cas qui cause uneinsertion continue denouveauxtransitoires quine sontpas utilisés,alors vous deveztrouver leproblème sous-jacent à laplace. Qu'est-ce que l'insertion de cestransitoires? Utilisent-ils une clé changeante oumutante? Sitelest le cas,alors leplugin ou le code causant cela devrait être corrigé,en gros,ne lefaitespas. Ce seraplus utile,carilestprobable que le code quine les créepas correctementne les récupèrepasnonplus,et doncfasseplus detravail qu'iln'en a àfaire.
D'un autre côté,ilpeut y avoir un cas où destransitoires sont crééspour quelque chose comme chaque article. Celapeuten effet êtreparfaitement acceptable. Je lefaismoi-même dans SFC,pour stocker les commentairesentrants de Facebook. Chaquepublicationest associée à untransitoirepotentiel,ce qui signifie deux lignes supplémentairesparpublication. Si vous avez 10 000publications,vous aurez 20 000 lignes dans letableau des options (éventuellement). Cen'estni mauvaisni lent,carencore unefois,il y atrèspeu de différenceentre 100 ligneset 20 000 lignesen ce qui concerne lesbases de données. Toutestindexé. C'est aussi rapide que diable. Sous-sous-millisecondes.
Lorsque vous commencez àentrer dans millions de lignes,je m'inquiète. Lorsque lataille de latable d'options augmente au-dessus de centaines demégaoctets,je serais suffisammentpréoccupépour y regarder deplusprès. Mais d'unemanièregénérale,cen'estpas unproblème,sauf dans les casextrêmes. Cen'est certainementpas unproblèmepour quelque chose depluspetit que quelque chose comme ungrand site d'actualités,avec des centaines demilliers demessages. Etpourtout site suffisammentgrandpour que celapose unproblème,vous devriez utiliser un cache d'objetsexterne,et dans ce cas,lestransitoires y sont automatiquement stockés au lieu d'être dans labase de données.
Moving some of the comments from the discussion into an answer, with re-wording and re-formatting..
Basically, what it comes down to is that unless you have a super extreme case, they don't really need to be "garbage collected". If you never fetch them, then it doesn't matter if they're there or not.
See, transients are stored in the options table by default. In a base install, the options table will have maybe 100 entries in it. Each transient adds two more entries, but even if you have thousands, they don't affect the site speed, since they're not autoloaded.
On startup, WordPress loads the options into memory, but it only loads options that have their autoload flag turned on. Transients don't get this, and so don't get loaded into memory. Only transients that get actually used later will incur a cost.
From the database's perspective, the options table has indexes on both the option Id and the option name. Transients are always loaded based on the name (key), and so the lookups for them are always simple selects on a single unique key value. Thus the lookup is O(log(n)) and is super fast. With a Big-O of log(n), you'd have to get into the millions and millions of rows before it became noticable. Frankly, the overhead in the setup and teardown of the query, along with the actual data transfer, is way longer. The query itself runs in essentially zero-time by comparison. So simply having extra unused rows doesn't affect anything but using extra disk space.
Indexing in databases is one of those deep-read kind of ideas that doesn't make sense to people who haven't actually understood what's going on behind the scenes. Databases are designed for fast data retrieval, from the ground up, and can handle this sort of thing without issues. This is a pretty good read: http://en.wikipedia.org/wiki/Index_(database)
Now, cleanup in the most obvious way (calling SQL DELETE on them) doesn't actually delete them from the database. It just removes them from the index and marks the row as "deleted". Again, this is just how databases work. To actually clear up the disk space, you have to then continue on and do an OPTIMIZE TABLE afterwards, and this is not a fast operation. It takes time. Probably more time than it's worth. It's probably not enough to give you a savings in CPU time, in total.
If you have some case that is causing a continual insertion of new transients that are not being used, then you need to find the underlying problem instead. What is inserting these transients? Are they using a changing or mutating key? If so, then the plugin or code causing this should be fixed to, basically, not do that. That will be more helpful, because it's likely that the code that isn't creating them properly also isn't retrieving them, and thus doing more work than it has to do.
On the other hand, there may be a case where transients are being created for something like every post. This may indeed be perfectly acceptable. I do this myself in SFC, to store incoming comments from Facebook. Each post has a potential transient associated with it, which means two extra rows per post. If you have 10k posts, you'll have 20k rows in the options table (eventually). This isn't bad or slow, because again, there's very little difference between 100 rows and 20,000 rows as far as databases really care. It's all indexed. It's fast as heck. Sub-sub-milliseconds.
When you start getting into millions of rows, then I'd be worried. When the options table size increases above hundreds of megabytes, then I'd be concerned enough to take a closer look. But generally speaking, this isn't an issue except for extreme cases. It's certainly not an issue for anything smaller than something like a large news site, with hundreds of thousands of posts. And for any site large enough for it to be a problem, you should be using an external object cache of some sort, and in that case, the transients get automagically stored there instead of in the database.
-
NB: lestransitoires sansexpiration ** do ** sont automatiquement chargés,et aucuneexpirationest la ** valeurpar défaut **,donc lorsqu'une application/plugin créebeaucoup detransitoireset ne définitpas d'expiration,ils utiliseront desmorceaux demémoire sur chaquechargement de lapage/publication.NB: transients with no expiration **do** get autloaded, and no expiration is the **default**, so where an application / plugin is creating lots of transients and not setting an expiration they will be using chunks of memory on every page/post load.
- 1
- 2013-07-29
- webaware
-
Iln'y a aucune raison d'utiliser un "transitoire sansexpiration",car c'estfondamentalementidentique à une "option"normale.There is no reason to use a "transient with no expiration", because that is basically identical to a normal "option".
- 0
- 2013-07-29
- Otto
-
Bien sûr,mais [c'est la valeurpar défaut] (http://codex.wordpress.org/Function_Reference/set_transient).Entant quetel,denombreux auteurs deplugins ajoutent destransitoiresnonexpirants.Sure, but [it's the default](http://codex.wordpress.org/Function_Reference/set_transient). As such, many plugin authors are adding non-expiring transients.
- 1
- 2013-07-30
- webaware
-
En outre,pasidentique à une option,carelle serapurgée lors de l'utilisation d'un cache d'objets - voir [article récent sur WPEngine] (http://wpengine.com/2013/02/wordpress-transient-api/)pourplus de détails.Also, not identical to an option, as it will be purged when using an object cache -- see [recent article on WPEngine](http://wpengine.com/2013/02/wordpress-transient-api/) for details.
- 0
- 2013-07-30
- webaware
-
Ehbien,la solutioniciest simple:n'utilisezpas cesplugins.Ils lefontmal.Lestransitoiresne doiventpas être utilisés comme sessions,vousne devezpas les utiliser sansexpiration significativeet ilsne doiventpas avoir de clésmutantes ou changeantes.Well, the solution here is simple: Don't use those plugins. They're doing it wrong. Transients are not to be used as sessions, you should not use them without a meaningful expiration, and they should not have mutating or changing keys.
- 1
- 2013-07-30
- Otto
-
:) (parce que cen'estpasparce que la valeurpar défaut de WordPressestfausse,hein?):) (because it's not because the WordPress default is wrong, eh?)
- 0
- 2013-07-31
- webaware
-
Ça dépend.Que considérez-vous comme une valeurpar défaut raisonnable à laplace?That depends. What would you consider a sensible default value there instead?
- 0
- 2013-07-31
- Otto
-
Dites,7jours.Si un auteur deplugin/thème veut quelque chose deplusgrand oupluspetit,il le spécifiera.S'ils veulent un chargement automatique,ilsne devraientpas avoir à spécifier 0pour l'expiration (=infini),mais c'est ce qu'ils ont actuellement avec leparamètre d'expirationfaisant doubleemploien tant queparamètre de chargement automatique oui/non.Quoi qu'ilen soit,l'expirationpar défautne devraitpas également conduire à autoload=yespar défaut;c'estjuste demander desennuis.Say, 7 days. If a plugin / theme author wants something bigger or smaller, they'll specify it. If they want autoload, they shouldn't have to specify 0 for expiration (= infinity), but that's what they've currently got with the expiration parameter doing double duty as the yes/no autoload parameter. Either way, default expiration shouldn't also lead to autoload=yes as default; that's just asking for trouble.
- 2
- 2013-08-01
- webaware
-
Àmon avis,ne pas spécifier d'expiration devraitgénérer uneerreurfataleet casser le site.Mais alorsje ne suispasen charge.Untransitoire sansexpirationest stupideet dénué de sens.Si vous souhaitez utiliser le cache d'objets,utilisez simplement le cache d'objets directement avec lesfonctions wp_cache.Cela dit,ilexiste desticketspour que lafuture version de WordPressnettoie les ancienstransitoires,principalementparce que c'est "disgracieux"plus quetoute autre chose.In my considered opinion, not specifying an expiration should throw a fatal error and break the site. But then I'm not in charge. A transient with no expiration is stupid and meaningless. If you want to use the object cache, then just use the object cache directly with the wp_cache functions. That said, there are tickets to have future version of WordPress clean up old transients, mainly because it's "unsightly" more than anything else.
- 1
- 2014-03-19
- Otto
-
- 2011-12-02
Otto - Jene pourraispas êtreplusen désaccord avec vous. Leproblèmeest quefinalement avectous cestransitoires,lataille de latable devient ridicule. Ilne fautpas desmillions de lignespour s'enliser. Je suis actuellement confronté à unetable d'options qui compteplus de 130 000 ligneset qui sebloque régulièrement. Étant donné que le champ de valeurest untype detexte volumineux,même la recherche des lignes «autoload» devient un cauchemar deperformances. Ces champs de valeur sont stockés séparément du reste des données de ligne. Même si celafait logiquementpartie de lamêmetable,lesjointures doivent seproduirepourextraire les lignes souhaitées. Desjointures quiprennent désormais une éternité car les données dont vous avezbesoin sont répartiespartout sur le disque. Leprofilage (en utilisantjet profilerpourmysql) l'aprouvé.
L'ajout du chargement automatique à la cléen clusterpeut aider à résoudre ceproblème. Le clustering sur Autoload Desc,ID ASCparexemple,permettrait àtoutes les lignes de chargement automatique de se regrouperen premier sur le disque. Mêmeencore,je pense que vous regardez une énorme souche dupoint de vue DB.
Personnellement,je pense que la conception de ce systèmeestfarfelue. Letableau des options semble s'êtretransforméen unfourre-toutgénéralpourbeaucoup de choses. C'estparfait si le champ de valeurest suffisammentpetit pour êtreinclus sur lamêmepage que le reste des données de ligneet peut êtreindexéefficacement. Cen'estmalheureusementpas le cas. Celui qui a conçu cela doit revenir à la classe DB101.
Otto - I couldn't disagree with you more. The issue is that eventually with all those transients, the size of the table becomes ridiculous. It doesn't take millions of rows to bog down. I'm currently dealing with an options table that has over 130k rows, and hangs regularly. Because the value field is a large text type, even looking for only the "autoload" rows becomes a nightmare of performance. Those value fields are stored separately from the rest of the row data. Even though it's logically part of the same table, joins must happen in order to pull up the rows you want. Joins that now take forever because the data you need is spread all over the place on disk. Profiling (using jet profiler for mysql) has proven this.
Adding auto-load to the clustered key might help solve this problem. Clustering on Autoload Desc, ID ASC for example, would allow all the autoload rows to bunch together first on disk. Even still I think you're looking at a huge strain from a DB perspective.
Personally I think the design of this system is wack. The options table seems to have turned into a general catch-all for a lot of things. That's fine if the value field is small enough to be included on the same page as the rest of the rowdata, and can be indexed effectively. Unfortunately that's not the case. Whoever designed this needs to go back to DB101 class.
-
vrai,mais considérez que lorsque le développement de WordPress a commencé,personnene pensait qu'il atteindrait desmilliers deplugins utilisant latable d'options comme stockage de données :)true, but consider that when WordPress development started, nobody thought that it would reach to have thousands of plugins using options table as their data storage :)
- 5
- 2011-12-02
- onetrickpony
-
@onetrickpony c'estpourquoiilestimportant detoujoursprendre sontempset debien faire les choses,que vous vous attendiez à ce que ce soit énorme unjour oupas :)@onetrickpony that's why it's important to always take your time and do things right, whether you expect it to be huge someday or not :)
- 0
- 2017-12-11
- Mahmoud Al-Qudsi
Cette questionm'afait réfléchir Flux RSStransitoires danswp_optionsn'estpas supprimé automatiquement?
Lestransitoires sont censésexpireret être supprimés.Cependant,la seulefaçon dontje vois celagéréest lorsque letransitoireestexpiréet demandé,puisilest supprimépendant la demande.
Que sepasse-t-il si letransitoire aexpirémaisn'ajamais été demandépar la suite?D'après la description du Codex,j'aipensé qu'une sorte de ramassage des ordures étaitimplicite.Maintenant,je ne suispas si sûret jene trouve aucun code quiexécute unetelle opération.
Alors,sera-t-ilbloquépourtoujours dans labase de données?