J'ai essayé de résoudre le problème suivant pendant environ une heure maintenant et je n'ai toujours pas pu aller plus loin.
D'accord, j'ai une table (MyISAM):
+---------+-------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| http | smallint(3) | YES | MUL | 200 | |
| elapsed | float(6,3) | NO | | NULL | |
| cached | tinyint(1) | YES | | NULL | |
| ip | int(11) | NO | | NULL | |
| date | timestamp | NO | MUL | CURRENT_TIMESTAMP | |
+---------+-------------+------+-----+-------------------+----------------+
S'il vous plaît, ne vous occupez pas des index, j'ai essayé de trouver une solution. Maintenant, voici ma requête.
SELECT http,
COUNT( http ) AS count
FROM reqs
WHERE DATE(date) >= cast(date_sub(date(NOW()),interval 24 hour) as datetime)
GROUP BY http
ORDER BY count;
le tableau stocke des informations sur les requêtes Web entrantes, c'est donc une base de données assez volumineuse.
+-----------+
| count(id) |
+-----------+
| 782412 |
+-----------+
notez qu'il n'y a pas de meilleur moyen de définir une clé primaire car la colonne id sera le seul identifiant unique que j'ai. La requête mentionnée ci-dessus prend environ 0,6 à 1,6 seconde pour s'exécuter.
Quel indice serait intelligent? J'ai pensé que la date d' indexation me donnerait une "mauvaise" cardinalité et donc MySQL ne l'utiliserait pas. http est également un mauvais choix car il n'y a qu'environ 20 valeurs possibles différentes.
Merci pour ton aide!
Mise à jour 1 J'ai ajouté un index sur (http, date) comme suggéré par ypercube:
mysql> CREATE INDEX httpDate ON reqs (http, date);
et utilisé sa requête, mais il a tout aussi mal fonctionné. L'index ajouté:
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| reqs | 0 | PRIMARY | 1 | id | A | 798869 | NULL | NULL | | BTREE | |
| reqs | 1 | httpDate | 1 | http | A | 19 | NULL | NULL | YES | BTREE | |
| reqs | 1 | httpDate | 2 | date | A | 99858 | NULL | NULL | | BTREE | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
et l' EXPLIQUER
+----+--------------------+-------+-------+---------------+----------+---------+------+-------+-----------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+-------+---------------+----------+---------+------+-------+-----------------------------------------------------------+
| 1 | PRIMARY | r | range | NULL | httpDate | 3 | NULL | 20 | Using index for group-by; Using temporary; Using filesort |
| 2 | DEPENDENT SUBQUERY | ri | ref | httpDate | httpDate | 3 | func | 41768 | Using where; Using index |
+----+--------------------+-------+-------+---------------+----------+---------+------+-------+-----------------------------------------------------------+
Version du serveur MySQL:
mysql> SHOW VARIABLES LIKE "%version%";
+-------------------------+---------------------+
| Variable_name | Value |
+-------------------------+---------------------+
| protocol_version | 10 |
| version | 5.1.73 |
| version_comment | Source distribution |
| version_compile_machine | x86_64 |
| version_compile_os | redhat-linux-gnu |
+-------------------------+---------------------+
5 rows in set (0.00 sec)
http
colonne pouvant être annulée. Je vais enquêter demain, si je trouve du temps.
http NOT NULL
) et en y copiant toutes les données (sauf les lignes avec http NULL bien sûr.)