【问题标题】:MySQL query is not using the indexMySQL 查询未使用索引
【发布时间】:2016-07-29 21:32:54
【问题描述】:

我有以下查询:

SELECT bank_code, bank_name
FROM system_bank_info
WHERE company_id=1 AND country_id=103 AND status='ACTIVE'
GROUP BY bank_name
ORDER BY bank_name ASC

表格架构:

CREATE TABLE `system_bank_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `company_id` int(11) NOT NULL,
  `country_id` int(11) NOT NULL,
  `bank_code` varchar(50) NOT NULL,
  `bank_name` varchar(255) NOT NULL,
  `branch_code` varchar(50) NOT NULL,
  `branch_name` varchar(255) NOT NULL,
  `status` enum('ACTIVE','INACTIVE') NOT NULL DEFAULT 'ACTIVE',
  `bank_state` varchar(255) DEFAULT NULL,
  `bank_district` varchar(255) DEFAULT NULL,
  `bank_city` varchar(255) DEFAULT NULL,
  `bank_address` text,
  `bank_contact` varchar(255) DEFAULT NULL,
  `service_type` enum('INSTA_CREDIT') DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `country_id` (`country_id`),
  KEY `bank_code` (`bank_code`),
  KEY `branch_code` (`branch_code`),
  KEY `company_id_country_id_status` (`company_id`,`country_id`,`status`),
  CONSTRAINT `system_bank_info_ibfk_1` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`),
  CONSTRAINT `system_bank_info_ibfk_2` FOREIGN KEY (`country_id`) REFERENCES `system_country_list` (`country_id`)
) ENGINE=InnoDB AUTO_INCREMENT=150398 DEFAULT CHARSET=utf8

解释:

+----+-------------+------------------+------+-----------------------------------------+------------+---------+-------+-------+----------------------------------------------+
| id | select_type | table            | type | possible_keys                           | key        | key_len | ref   | rows  | Extra                                        |
+----+-------------+------------------+------+-----------------------------------------+------------+---------+-------+-------+----------------------------------------------+
| 1  | SIMPLE      | system_bank_info | ref  | country_id,company_id_country_id_status | country_id | 4       | const | 59324 | Using where; Using temporary; Using filesort |
+----+-------------+------------------+------+-----------------------------------------+------------+---------+-------+-------+----------------------------------------------+

如您所见,有一个名为company_id_country_id_status 的索引。但是,查询仍然只使用country_id。如何让这个查询更有效率?

我还尝试添加索引bank_codebank_name。但是,同样的结果!

【问题讨论】:

  • 如果country_idcompany_id 都是int 类型,为什么在查询中将它们作为字符串传递?另外,您能否量化一下您面临的性能问题,让我们知道company_id 1 和country_id 103 以及整个表格中有多少行?
  • 124294 行与company_id 1 和country_id 103
  • 如果company_id 不是选择性索引(低基数),那么 MySQL 将不会使用它,因为它是一种浪费并且不会产生任何性能。你说有124294 行和country_id = 1 - 这意味着它的基数很低并且它是一个无用的索引(它只是在浪费空间并且不能帮助产生任何性能)。您可以强制 MySQL 使用它,但它不会使查询更快 - 恰恰相反。
  • @Mjh:我在这里发现了一些东西。当我使用country_id = 210 时。然后它使用这个索引:company_id_country_id_status。 Bcoz 210 的数据少于 103。
  • 这只是证实了我所说的......索引只有在它们的选择性很高时才有用。如果你有一个没有选择性的索引,MySQL 会选择不使用它。基本上,你不能在那里做任何事情 - 保持原样,它工作正常。

标签: php mysql performance indexing query-performance


【解决方案1】:

您可以向优化器提供提示,以便它使用特定的索引。 USE INDEX ()

SELECT bank_code, bank_name
FROM system_bank_info USE INDEX (company_id_country_id_status)
WHERE company_id=1 AND country_id=103 AND status='ACTIVE'

【讨论】:

  • 我也试过这个。但是,它并没有提高查询性能。相同的执行时间。
  • @RonakPatel 什么执行时间? (此外,强制使用索引并没有帮助表明查询优化器可能正确地完成了它的工作——它知道它没有帮助,所以它没有费心使用它。)
猜你喜欢
  • 2011-07-22
  • 2014-12-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-10
  • 1970-01-01
  • 2013-09-16
  • 2021-12-20
相关资源
最近更新 更多