繁体   English   中英

优化耗时约4分钟的mysql查询

[英]Optimize mysql query that take long execution time about 4 minutes

 select nl.ndc, formulary_status FROM bh.webdav_formulary_detail wfd 
 INNER JOIN bh.payer_map pm ON wfd.payer_map_id = pm.payer_map_id 
 INNER JOIN bh.ndc_lookup nl ON wfd.product_id = nl.uid 
 WHERE pm.payer_id ='P00000000001001' 
   and pm.formulary_id='01244' 
   and nl.ndc in ('16590061572' , '35356078830' , '35356078860' , '35356078890' , 
                  '49999085690' , '54868381500' , '54868381501' , '54868381503' , 
                  '54868381504' , '54868381505' , '59011044010' , '59011044020' , 
                  '63629377401' , '63629377402' , '63629377403');

下面的mysql表是myisam引擎

SHOW CREATE TABLE webdav_formulary_detail;

CREATE TABLE webdav_formulary_detail (
  product_id mediumint(8) unsigned NOT NULL,
  formulary_status char(2) NOT NULL,
  file_iid smallint(5) unsigned NOT NULL DEFAULT '0',
  payer_map_id smallint(5) unsigned NOT NULL,
  KEY payer_map_id (payer_map_id),
  KEY product_id (product_id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

CREATE TABLE ndc_lookup (
  uid mediumint(8) unsigned NOT NULL,
  ndc char(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (uid),
  KEY uid (uid),
  KEY ndc (ndc)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

CREATE TABLE payer_map (
  payer_map_id smallint(5) unsigned NOT NULL,
  payer_id varchar(80) DEFAULT NULL,
  formulary_id varchar(50) DEFAULT NULL,
  alternate_id varchar(50) DEFAULT NULL,
  PRIMARY KEY (payer_map_id),
  KEY payer_map_id (payer_map_id),
  KEY payer_id (payer_id),
  KEY formulary_id (formulary_id),
  KEY alternate_id (alternate_id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 

我如何优化上述mysql查询以将其执行时间缩短到不到半分钟?

WHERE pm.payer_id ='P00000000001001' 
  and pm.formulary_id='01244' 

payer_map上请求一个综合索引: INDEX(payer_id, formulary_id) (或相反的顺序)。 稍微好一点的将是切换到InnoDB或创建一个“覆盖”索引: INDEX(payer_id, formulary_id, payer_map_id)

  1. 优化器很可能从具有最佳过滤可能性的表开始-pm。 我给您的INDEX可以提高效率。
  2. 下一个表必须是wfd ,使用payer_map_id wfd对此有很好的索引。
  3. 最后, nl将使用uid进入。 再次有一个很好的索引。 实际上,由于是“覆盖”索引,因此INDEX(uid, ndc)会稍微好一些。 或者因为PRIMARY KEY的“聚集”而切换到InnoDB会很好。

始终提供EXPLAIN SELECT...; 看看优化器在做什么。

与优化无关:

PRIMARY KEY      (payer_map_id),
KEY payer_map_id (payer_map_id),

PRIMARY KEYUNIQUE KEYKEY ,因此后者是完全冗余的; DROP它。 uid

我的食谱有更多关于如何从SELECT创建索引的信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM