質問

I have these tables:

CREATE TABLE  `cstat` (
  `id_cstat` bigint(20) NOT NULL,
  `lang_code` varchar(3) NOT NULL,
  `description` varchar(255) NOT NULL,
  `description_tr` varchar(255) NOT NULL,
  `id_ccountry` varchar(3) NOT NULL,
  `geometry_point` point DEFAULT NULL,
  `geometry_poly` polygon DEFAULT NULL,
  `name_type` varchar(1) NOT NULL,
  `bb_min_lat` double DEFAULT NULL,
  `bb_min_lon` double DEFAULT NULL,
  `bb_max_lat` double DEFAULT NULL,
  `bb_max_lon` double DEFAULT NULL,
  `has_ex` tinyint(1) NOT NULL DEFAULT '0',
  `order` int(11) DEFAULT NULL,
  PRIMARY KEY (`id_cstat`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

CREATE TABLE  `dstat` (
  `id_cstat` bigint(20) NOT NULL,
  `lang_code` varchar(3) NOT NULL,
  `word` varchar(30) NOT NULL,
  `word_no` tinyint(3) unsigned NOT NULL,
  `word_cnt` tinyint(3) unsigned NOT NULL,
  `word_grp` tinyint(3) unsigned NOT NULL,
  `name_type` char(1) CHARACTER SET ascii NOT NULL,
  `cstat_order` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

I need to select a record from cstat using conditions from dstat and in order of cstat.order or dstat.cstat_order.

My query look like this:

SELECT cstat.ID_CSTAT, cstat.LANG_CODE, cstat.DESCRIPTION, cstat.DESCRIPTION_TR, cstat.ID_CCOUNTRY, AsBinary(cstat.GEOMETRY_POINT) AS GEOMETRY_POINT, cstat.NAME_TYPE, cstat.BB_MIN_LAT, cstat.BB_MIN_LON, cstat.BB_MAX_LAT, cstat.BB_MAX_LON, cstat.HAS_EX
FROM cstat cstat
JOIN dstat W0
ON (W0.ID_CSTAT = cstat.ID_CSTAT)
where
  (W0.WORD = 'ceska') AND
  (W0.NAME_TYPE = 'B')
ORDER BY W0.CSTAT_ORDER;

Can anybody help me what index to create to prevent using filesort? I believe I've tried almost everything, but I failed. There are more modifications of this base query (another one or more joins of table dstat, but thats not important right now).

Thanks a lot for your help.

EDIT: To be honest - I've tried a lot of indexes. The base one I've declared is a primary key on cstat_id_cstat. At the moment I have following indexes:

KEY `ix_dstat_nt_word_id_order` (`name_type`,`word`,`id_cstat`,`cstat_order`);
KEY `ix_dstat_word_id_order` (`word`,`id_cstat`,`cstat_order`);
KEY `ix_dstat_nt_grp_no_word_id_order` (`name_type`,`word_grp`,`word_no`,`word`,`id_cstat`,`cstat_order`);
KEY `ix_dstat_grp_no_word_id_order` (`word_grp`,`word_no`,`word`,`id_cstat`,`cstat_order`);
KEY `ix_dstat_nt_grp_word_id_order` (`name_type`,`word_grp`,`word`,`id_cstat`,`cstat_order`);

which partly solves my problem with indexed reading. But sort is always made by using filesort.

EXPLAIN

1, 'SIMPLE', 'W0', 'ref', 'ix_dstat_nt_word_id_order,ix_dstat_word_id_order,ix_dstat_nt_grp_no_word_id_ord‌​er,ix_dstat_nt_grp_word_id_order', 'ix_dstat_nt_word_id_order', '93', 'const,const', 1, 'Using where; Using index; Using filesort' 
1, 'SIMPLE', 'cstat', 'eq_ref', 'PRIMARY,ix_cstat_id_order', 'PRIMARY', '8', 'search_2012_q3_cze_svk_dev.W0.id_cstat', 1, ''
役に立ちましたか?

解決 3

Problem is solved by adding following indexes:

KEY `ix_dstat_nt_word_order_id_grp_no` (`name_type`,`word`,`cstat_order`,`id_cstat`,`word_grp`,`word_no`);
KEY `ix_dstat_word_order_id_grp_no` (`word`,`cstat_order`,`id_cstat`,`word_grp`,`word_no`);

他のヒント

looks like you should have one index on cstat.id_cstat and one on dstat for word, and name_type

alter your table and add index on column id_cstat on table dstat

ALTER TABLE dstat ADD INDEX tb_idx(id_cstat)

so it will not require full table scan, then also on table cstat

ALTER TABLE cstat ADD INDEX tba_idx(`order`)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top