Mysql没有正确使用我的索引

时间:2014-07-23 16:03:13

标签: mysql indexing

首先对不起,我是法国人,我说英语不太好。

我的索引有一个相当奇怪的问题。

我的表t_bloc(我的表包含所有帖子)

t_bloc
CREATE TABLE `t_bloc` (
 `id_bloc` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `id_rubrique` int(10) unsigned NOT NULL DEFAULT '0',
 `titre` varchar(100) NOT NULL DEFAULT 'A compléter',
 `contenu` text NOT NULL,
 `titre_page` varchar(100) NOT NULL,
 `desc_courte` varchar(255) NOT NULL,
 `url` varchar(255) NOT NULL,
 `follow_url` tinyint(1) unsigned NOT NULL DEFAULT '1' ,
 `image` varchar(120) NOT NULL,
 `video` varchar(120) NOT NULL,
 `note` tinyint(3) unsigned NOT NULL DEFAULT '0',
 `champopt1` text NOT NULL,
 `champopt2` text NOT NULL,
 `permalien` varchar(100) NOT NULL,
 `en_ligne` tinyint(1) NOT NULL DEFAULT '0',
 `id_utilisateur` int(10) unsigned NOT NULL DEFAULT '1' ,
 `date_crea` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `date_modif` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `nb_commentaires` smallint(5) unsigned NOT NULL DEFAULT '0',
 `nb_jaimes` int(10) unsigned NOT NULL DEFAULT '0',
 `nb_jaimespas` int(10) unsigned NOT NULL DEFAULT '0',
 `pourcentage_jaimes` smallint(2) unsigned NOT NULL DEFAULT '0' ,
 `niveau_classement` tinyint(1) unsigned NOT NULL DEFAULT '1' ,
 `id_bloc_parent` int(10) unsigned NOT NULL DEFAULT '0' ,
 `id_membre_bloc` int(10) unsigned NOT NULL DEFAULT '0' ,
 `valeur_pts_bloc` smallint(5) unsigned NOT NULL DEFAULT '0' ,
 `commentaires_actifs` tinyint(1) unsigned NOT NULL DEFAULT '1' ,
 PRIMARY KEY (`id_bloc`),
 KEY `date_modif` (`date_modif`),
 KEY `id_bloc_parent` (`id_bloc_parent`),
 KEY `idx_rub_ligne_niv_etc` (`id_rubrique`,`en_ligne`,`niveau_classement`,`note`,`pourcentage_jaimes`,`date_modif`),
 KEY `idx_tri` (`en_ligne`,`niveau_classement`,`note`,`pourcentage_jaimes`,`date_modif`),
 KEY `idx_ligne_membre` (`en_ligne`,`id_membre_bloc`,`id_rubrique`),
 KEY `id_membre_bloc` (`id_membre_bloc`),
 KEY `idx_rub_ligne_date` (`id_rubrique`,`en_ligne`,`date_modif`,`id_bloc`),
 KEY `idx_ligne_date` (`en_ligne`,`date_modif`),
 FULLTEXT KEY `idx_fullindex` (`titre`,`contenu`)
) ENGINE=MyISAM AUTO_INCREMENT=456469 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC

我的表t_taxon_bloc

t_taxon_bloc
CREATE TABLE `t_taxon_bloc` (
 `id_taxon` int(10) unsigned NOT NULL,
 `id_bloc` int(10) unsigned NOT NULL,
 `url_plateforme` varchar(255) NOT NULL,
 `width_flash` smallint(5) unsigned NOT NULL,
 `height_flash` smallint(5) unsigned NOT NULL,
 PRIMARY KEY (`id_taxon`,`id_bloc`),
 KEY `id_bloc` (`id_bloc`),
 KEY `id_taxon` (`id_taxon`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC

执行此查询时出现问题:

 select b.id_bloc FROM t_bloc as b WHERE b.en_ligne = 1 AND EXISTS ( SELECT 1 FROM t_taxon_bloc AS TB WHERE TB.id_bloc=B.id_bloc AND TB.id_taxon= 83) ORDER BY b.en_ligne DESC, b.date_modif DESC LIMIT 0, 20

我得到以下解释

id 
select_type 
table 
type 
possible_keys 
key 
key_len 
ref 
rows 
Extra 

1
PRIMARY
b
ref
idx_tri,idx_ligne_membre,idx_ligne_date
idx_ligne_date
1
const
58210
Using where

2
DEPENDENT SUBQUERY
TB
eq_ref
PRIMARY,id_bloc,id_taxon
PRIMARY
8
const,sitajeuxtestbourrage.b.id_bloc
1
Using index

它没有完全使用idx_ligne_date索引和行=表中的所有行

额外=«使用Where»

如果我创建以下索引 idx_ligne_date_idbloc(en_ligne,date_modif,id_bloc), 使用索引要好一点,应用程序运行得快一点。

id 
select_type 
table 
type 
possible_keys 
key 
key_len 
ref 
rows 
Extra 

1
PRIMARY
b
ref
idx_tri,idx_ligne_membre,idx_ligne_date_idbloc
idx_ligne_date_idbloc
1
const
58252
Using where; Using index

2
DEPENDENT SUBQUERY
TB
eq_ref
PRIMARY,id_bloc,id_taxon
PRIMARY
8
const,sitajeuxtestbourrage.b.id_bloc
1
Using index

额外=«使用Where,使用索引»

我的问题:

id_bloc没有出现在where和order by子句中,为什么我需要在我的多个索引上添加id_bloc? 为什么行=(再次)我的所有表?而不是20(LIMIT 0,20)

1 个答案:

答案 0 :(得分:0)

您似乎误解了“使用索引”在“额外”列中的含义。看看这个法语解释:http://use-the-index-luke.com/fr/sql/plans-dexecution/mysql/operations

  

id_bloc没有出现在where和order by子句中,为什么我需要在我的多个索引上添加id_bloc?

您不需要,但这样做允许所谓的仅索引扫描(在Extra中使用“Using Index”字样表示)。您可以在此法语页面了解仅索引扫描:http://use-the-index-luke.com/fr/sql/regrouper-les-donnees/parcours-d-index-couvrants