lundi 22 mars 2010

Revue des blogs #238 : Une liste de news très Geek

revue,blog,news,geek


bullet Abonnez-vous à ces revues par feed rss news geek ou par email news geek
bullet Découvrez les anciennes revues

lundi 14 décembre 2009

Astuce Dotclear #6 : Lister les plus gros commentateurs

Vous chercher à lister les plus gros commentateurs de votre blog Dotclear ?

Voici une requête SQL qui vous permettra d'obtenir la liste des 100 plus gros commentateurs par ordre descendant de commentaires postés.

SELECT DISTINCT dc_comment.comment_email, comment_author,  COUNT( dc_comment.comment_id ) AS countComment
FROM  `dc_comment`
GROUP BY dc_comment.comment_email
ORDER BY countComment DESC
LIMIT 0 , 100

Sur Geeek, les plus gros commentateurs d'articles sont :

  1. spawnrider
  2. maley
  3. pyknite
  4. Worx
  5. Kara-ci.info
  6. entraks
  7. wan
  8. borkmadjai
  9. 404
  10. Damien ALEXANDRE
  11. SiMON
  12. Nonepse
  13. pyknite
  14. Delfkhyn
  15. Modérateur
  16. mrnico
  17. joris

Merci à vous ;-)

dimanche 19 juillet 2009

Revue des blogs #164 : Une liste de news très Geek !

revue,blog,news,geek


bullet Abonnez-vous à ces revues par feed rss news geek ou par email news geek
bullet Découvrez les anciennes revues

mercredi 11 février 2009

Optimisation MySQL : Une solution simple pour optimiser sa base MySQL

mysql optimisation Slow Query Log Max Connections Worker Threads Sort Buffer Joins

Vous possédez une base MySQL que vous souhaitez optimiser ? Vous n'êtes pas un expert MySQL et vous ne comprenez pas vraiment tous les paramètres contenus dans le fichier de configuration de votre instance MySQL ?

Et bien je pense avoir trouvé la réponse à votre problème :

http://day32.com/MySQL/tuning-primer.sh

Il s'agit d'un script Shell qui permet de faire des préconisations à chaud de votre base de données. Il vous donne un ensemble d'astuces en fonction de l'utilisation réelle que vous faites de votre base :

  • Slow Query Log
  • Max Connections
  • Worker Threads
  • Key Buffer
  • Query Cache
  • Sort Buffer
  • Joins
  • Temp Tables
  • Table (Open & Definition) Cache
  • Table Locking
  • Table Scans (read_buffer)
  • Innodb Status

Il suffit d'exécuter le script et de modifier le fichier de configuration de votre base en fonction des recommandations faites.

mysql_optimizer.jpg

Merci à Jordi Mir d'avoir déniché ce script !

dimanche 30 mars 2008

Astuce SQL : Comment remplacer toutes les occurences d'une chaine de caractère dans une table en base de données ?

La commande est très simple et très pratique :

UPDATE table_name SET column_name = REPLACE(column_name,"original_string","replace_string")

dimanche 18 novembre 2007

Optimisation de Dotclear 2 Beta 7 : La face cachée de la base de données

dotclear2,sql,performance

Après mon précédent article concernant quelques pistes d'optimisations de Dotclear 2, voici un nouvel article qui liste quelques pistes d'optimisations pour la base de données de Dotclear2 beta 7.

Remarque : Je tiens à mettre l'accent sur le "beta 7" car ces optimisations ne seront pas forcément applicables à la beta 8 ...

1) Tracker les requêtes SQL les plus lentes

Dotclear2 étant développé très proprement (merci à l'équipe de développement de Dotclear2), toutes les requêtes SQL passent par un composant qui se nomme "dblayer", qui est une couche d'abstraction à l'accès de la base de données.

inc/clearbricks/dblayer/

Cette couche permet à Dotclear2 de communiquer proprement avec sa base de données, celle-ci est composée d'une classe php "dblayer.php" et de plusieurs autres classes spécifiques aux bases de données que Dotclear 2 supporte.

Après une étude rapide du fichier dblayer.php, on se rend très vite compte que les requêtes de consultation "select" passent par la méthode "select()" de la classe dbLayer présent dans le fichier.

Pour connaitre la liste des requêtes SQL les plus longue, il suffit donc de tracer les requêtes depuis cette méthode ;-)

Voici la méthode "select()" avant patch:

public function select($sql)
        {
                $result = $this->db_query($this->__link,$sql);

                $this->__last_result =& $result;

                $info = array();
                $info['con'] =& $this;
                $info['cols'] = $this->db_num_fields($result);
                $info['rows'] = $this->db_num_rows($result);
                $info['info'] = array();

                for ($i=0; $i<$info['cols']; $i++) {
                        $info['info']['name'][] = $this->db_field_name($result,$i);
                        $info['info']['type'][] = $this->db_field_type($result,$i);
                }

                return new record($result,$info);
        }

Et la voici après patch :

public function select($sql)
        {
                $starttime = microtime();
                $result = $this->db_query($this->__link,$sql);
                $endtime = microtime();

                $tracesql = false;
                $totaltime = $endtime - $starttime;

                // Si la requête est plus longue que 0.5 secondes
                if ($totaltime > 0.5 ){
                        $tracesql = true;
                }

                // On trace la requête SQL
                if ($tracesql){

                        $fp = fopen("/tmp/db.log", "a");

                        $data = $totaltime . ";" . $sql . "\n";

                        // Write the data to the file
                        fwrite($fp, $data);

                        // Close the file
                        fclose($fp);
                }

                $this->__last_result =& $result;

                $info = array();
                $info['con'] =& $this;
                $info['cols'] = $this->db_num_fields($result);
                $info['rows'] = $this->db_num_rows($result);
                $info['info'] = array();

                for ($i=0; $i<$info['cols']; $i++) {
                        $info['info']['name'][] = $this->db_field_name($result,$i);
                        $info['info']['type'][] = $this->db_field_type($result,$i);
                }

                return new record($result,$info);
        }

Cette modification devrait nous permettre de tracer les requêtes select qui répondent en plus de 0.5 secondes dans un fichier qui se nomme "db.log" et qui sera créé dans le répertoire temporaire "/tmp".

2) Analyse de requêtes SQL

Après un peu de trafic le blog, vous devriez obtenir des requêtes SQL dans le fichier "/tmp/db.log". Si ce n'est pas le cas, soit votre blog ne contient pas beaucoup d'articles, soit vous avez un serveur avec pas mal de CPU ;-)

Note: Le premier chiffre qui se trouve devant la requête est le temps d'exécution de celle-ci.

Voici les trois requêtes SQL les plus redondantes qui ont été tracées sur mon blog. Les requêtes tracées dépendent énormément de la configuration de votre blog, de la quantité d'articles que contient votre blog, et de la qualité de votre hébergement Web :

SELECT meta_id, meta_type, COUNT(M.post_id) AS count FROM dc_meta M LEFT JOIN dc_post P ON M.post_id = P.post_id WHERE P.blog_id = 'default'  AND meta_type = 'tag' AND ((post_status = 1 AND post_password IS NULL ) ) GROUP BY meta_id,meta_type,P.blog_id ORDER BY count DESC LIMIT 50

SELECT P.post_id, P.blog_id, P.user_id, P.cat_id, post_dt, post_tz, post_creadt, post_upddt, post_format, post_password, post_url, post_lang, post_title, post_excerpt, post_excerpt_xhtml, post_content, post_content_xhtml, post_notes, post_type, post_meta, post_status, post_selected, post_open_comment, post_open_tb, nb_comment, nb_trackback, U.user_name, U.user_firstname, U.user_displayname, U.user_email, U.user_url, C.cat_title, C.cat_url FROM dc_post P INNER JOIN dc_user U ON U.user_id = P.user_id LEFT OUTER JOIN dc_category C ON P.cat_id = C.cat_id WHERE P.blog_id = 'default' AND ((post_status = 1 AND post_password IS NULL ) ) AND post_type = 'post' AND (       (post_dt = '2006-03-29 22:49:37' AND P.post_id < 315)        OR post_dt < '2006-03-29 22:49:37' )  ORDER BY post_dt DESC, P.post_id DESC  LIMIT 1

SELECT C.comment_id, comment_dt, comment_tz, comment_upddt, comment_author, comment_email, comment_site, comment_content,  comment_trackback, comment_status, comment_spam_status, comment_spam_filter, comment_ip, P.post_title, P.post_url, P.post_id, P.post_password, P.post_dt, P.user_id, U.user_email, U.user_url FROM dc_comment C INNER JOIN dc_post P ON C.post_id = P.post_id INNER JOIN dc_user U ON P.user_id = U.user_id WHERE P.blog_id = 'default' AND ((comment_status = 1 AND P.post_status = 1 AND post_password IS NULL ) ) ORDER BY comment_dt DESC  LIMIT 10

La première chose à vérifier est que les éléments présents après le "WHERE" des requêtes possèdent bien un index en base :

  • Sur la première requête, il manque des index sur meta_type, post_status et post_password.
  • Sur la deuxième requête, il manque un index sur post_type.
  • Sur la dernière requête, il manque un index sur comment_status et comment_dt

Voici les requêtes SQL pour créer ces index en base :

ALTER TABLE `dc_post` ADD INDEX ( `post_status` , `post_password` )  ;
ALTER TABLE `dc_post` ADD INDEX ( `post_type` )  ;

ALTER TABLE `dc_meta` ADD INDEX ( `meta_type` )  ;

ALTER TABLE `dc_comment` ADD INDEX ( `comment_status` )  ;
ALTER TABLE `dc_comment` ADD INDEX ( `comment_dt` )  ;

Après ces modifications, les requêtes que vous trouverez dans votre fichier db.log devraient être moins nombreuses. J'ai ouvert un post sur le forum de Dotclear2, mais je n'ai pas encore de réponse quand à mes optimisations.

Je souhaite remercier l'équipe Dotclear2 pour leur travail et les féliciter de cet merveilleux outil qu'est Dotclear2 !