簡體   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