MySQL与子查询结果进行比较时不使用主索引

时间:2016-11-15 12:19:35

标签: mysql

我的表格具有相同的架构

<div style="height: 260px" data-highchart="yes" data-encoded="*7JyYoFmc0JiO#7JCd5BXZiojIhJXZhJSfsICbldWZuRmI6snIl5WYixWZkJiOmFGbzVWfsIyc$lJXalNnI6s1ei4WYtVmI6ISQkZXYuRXYnVmIsIyYvx2byJiOiMSOyEUNyUjI]sIibldWY0lmdlN0bs9mciojIjMkMzMkMBJCLiYWasx2TwF2YpRXeioDMuQDL$iQHayV2co9GbkJiOw4CMsICbp5WZXlGZ0hmI6QDLiQWY0FmI6s1W2ADLxIjN#dxyWxIDMsIDMz0FLbFDOwwSL0kTOdxyWyQDMsMDNz0FLbNDMwwSM3kTXss1M#2ADL5UDOdxyW0IDMsUTN50FLbRDOwwiM4UDOdxyW1QDMsQTO20FLbZDMwwiN*4YTXsslN2ADL0gzMdxyW3IDMs0SMzkTXss1N4ADLtcjMy0FLbhDNwwSLyYjM]30FLblDMwwSLykTM00FLbljNwwSLyQzNy0FLbFDMyADLtEDNycTXssVMwgDM$s0SO0ATXssVMxQDMs0SM5czMdxyWxIDMwwSLxQTO00FLbFjM2ADLtEDNxgTX&amp;ssVMzIDMs0SMygTMdxyWxMDOwwSLxIDO20FLbFDN0ADLzEzN20FLbFTNwADL#0IjM50FLbFTN2ADL4IzN40FLbFjNyADL5ITN30FLbFjN4ADLxQDMxATXssVM]3QDMsEDN0kDMdxyWxgDMwwSM0IzMy0FLbFDO2ADLxUTM1ATXdxiItFmcrVmc@iozeiUmbhJGblRmI6YWYsNXZ91XXsISZ4RnchNnI6snI4FEepNnRvJXbhRnI&amp;6ICZ1JXY0l2buJCLiQ3bvxGdpBnRvJXbhRnI6ICdlFWbBRmdh5GdhdWZi0Xf" data-annotated="true"></div></div><div class="r-tab r-group-2" style="display:block; width: 100%"><div style="height: 260px" data-highchart="yes" data-encoded="}7JyYoFmc0JiO&amp;7JCd5BXZiojIhJXZhJSfsICbldWZuRmI6snIl5WYixWZkJiOmFGbzVWfsIyc]lJXalNnI6s1ei4WYtVmI6ISQkZXYuRXYnVmIsIyYvx2byJiOiMSOyEUNyUjI*sIibldWY0lmdlN0bs9mciojIjMkMzMkMBJCLiYWasx2TwF2YpRXeioDMuQDL$iQHayV2co9GbkJiOw4CMsICbp5WZXlGZ0hmI6QDLiQWY0FmI6s1W2ADL3ATX]ssVMyADLxYjNdxyWxgDMsEDM40FLbJDNwwyN0kTXss1MwADL2IzNdxyWzYDM]sEjNzQTXssFNyADLxUjM10FLbRDOwwSM3YjNdxyW1QDMsMTM00FLbZDMwwyN@2QTXsslN2ADLyMjNdxyW3IDMs0SMzUzMdxyW3gDMs0SM4EDNdxyW4QDMs0iM$0QTMdxyW5ADMs0CNykDMdxyW5YDMs0CNxUzNdxyWxAjMwwSLzMzNw0FLbFDM]4ADLtMzMyMTXssVMxQDMs0SNxMDOdxyWxIDMwwSL1QTN10FLbFjM2ADLtQTO#2kTXssVMzIDMs0SNyUzNdxyWxMDOwwSL2ADO10FLbFDN0ADLtIzM5YTXssVM]1ADMs0iNwATXssVM1YDMsEzN5MTXssVM2IDMsIzMwcTXssVM2gDMsQzM4ITX@ssVM3QDMsQTOzcTXssVM4ADMsQjN0ETXssVM4YDMsQjM4gTXdxiItFmcrVmc&amp;iozeiUmbhJGblRmI6YWYsNXZ91XXsISZ4RnchNnI6snI4FEepNnRvJXbhRnI#6ICZ1JXY0l2buJCLiQ3bvxGdpBnRvJXbhRnI6ICdlFWbBRmdh5GdhdWZi0Xf" data-annotated="true"></div></div><div class="r-tab r-group-3" style="display:block; width: 100%"><div style="height: 260px" data-highchart="yes" data-encoded="#7JyYoFmc0JiO@7JCd5BXZiojIhJXZhJSfsICbldWZuRmI6snIl5WYixWZkJiOmFGbzVWfsIyc$lJXalNnI6s1ei4WYtVmI6ISQkZXYuRXYnVmIsIyYvx2byJiOiMSOyEUNyUjI}sIibldWY0lmdlN0bs9mciojIjMkMzMkMBJCLiYWasx2TwF2YpRXeioDMuQDL$iQHayV2co9GbkJiOw4CMsICbp5WZXlGZ0hmI6QDLiQWY0FmI6s1W2ADLyQTM$dxyWxIDMsIDM40FLbFDOwwSL4ATOdxyWyQDMs0SMwQTXss1MwADLtgzMdxyW]zYDMscDNy0FLbRjMwwSOxATXssFN4ADLyMDO10FLbVDNwwiM1cTXsslNwADL#2QzNdxyW2YDMsQTO00FLbdjMwwSLycTNdxyW3gDMs0yN4gTXssFO0ADLtITM&amp;0UTXssVOwADLtIjM1cTXssVO2ADLtIjMxUTXssVMwIDMs0SM1kTOdxyWxADO}wwSL5YjMdxyWxEDNwwSLxYTO50FLbFjMwADLtEjNyATXssVMyYDMs0SMwUTO&amp;dxyWxMjMwwSL4cjMdxyWxMDOwwSLxEjM30FLbFDN0ADLyIzN00FLbFTNwADL@zATN30FLbFTN2ADL2MDNy0FLbFjNyADL2kTN20FLbFjN4ADLxETM1ETXssVM@3QDMsETMyczNdxyWxgDMwwSMwkDM50FLbFDO2ADLxIzMxcTXdxiItFmcrVmc*iozeiUmbhJGblRmI6YWYsNXZ91XXsISZ4RnchNnI6snI4FEepNnRvJXbhRnI}6ICZ1JXY0l2buJCLiQ3bvxGdpBnRvJXbhRnI6ICdlFWbBRmdh5GdhdWZi0Xf" data-annotated="true"></div></div></div>

当我执行此查询时,mysql使用了索引

CREATE TABLE `stock` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `currency` varchar(3) COLLATE utf8_unicode_ci NOT NULL,
  `against` varchar(3) COLLATE utf8_unicode_ci NOT NULL,
  `date` date NOT NULL,
  `time` time NOT NULL,
  `rate` double(8,4) NOT NULL,
  `ask` double(8,4) NOT NULL,
  `bid` double(8,4) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  KEY `stock_currency_index` (`currency`),
  KEY `stock_against_index` (`against`),
  KEY `stock_date_index` (`date`),
  KEY `stock_time_index` (`time`),
  KEY `created_at_index` (`created_at`)
) ENGINE=InnoDB AUTO_INCREMENT=244221 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

此外,当我执行此查询时,mysql也使用了主索引

mysql> explain select max(id) from stock group by currency;
+----+-------------+-------+------------+-------+----------------------+----------------------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type  | possible_keys        | key                  | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+-------+------------+-------+----------------------+----------------------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | stock | NULL       | range | stock_currency_index | stock_currency_index | 11      | NULL |    2 |   100.00 | Using index for group-by |
+----+-------------+-------+------------+-------+----------------------+----------------------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)

但当我结合这两个查询PRIMARY索引没有使用...我很困惑。我做错了什么?

mysql> explain select * from stock where id in (244221, 244222);
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | stock | NULL       | range | PRIMARY       | PRIMARY | 4       | NULL |    2 |   100.00 | Using where |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

1 个答案:

答案 0 :(得分:1)

首先,尝试将查询重写为:

select s.*
from stock s join
     (select max(id) as maxid
      from stock
      group by currency
     ) ss
     on ss.maxid = s.id;

其次,我很想在stock(currency, id)上放一个索引并使用:

select s.*
from stock s
where s.id = (select max(s2.id) from stock s2 where s2.currency = s.currency);

这些中的任何一个都表现得更好吗?